[MPlayer-dev-eng] [PATCH] Fix compilation against latest FFmpeg.

Reimar Döffinger Reimar.Doeffinger at gmx.de
Thu Apr 29 23:46:41 EEST 2021


Only for MPlayer, mencoder needs more changes.
---
 Makefile                    |  4 +-
 av_helpers.c                | 91 +++++++++++++++++++++++++++++++++++++
 av_helpers.h                |  4 ++
 libmpcodecs/ad_spdif.c      |  4 +-
 libmpcodecs/vd_ffmpeg.c     |  8 +++-
 libmpcodecs/vf.c            |  2 +-
 libmpcodecs/vf_lavc.c       | 35 +++++++-------
 libmpcodecs/vf_screenshot.c | 29 ++++++------
 libmpdemux/demux_lavf.c     | 13 ++++--
 sub/av_sub.c                | 14 +++---
 10 files changed, 154 insertions(+), 50 deletions(-)

diff --git a/Makefile b/Makefile
index 56fb7780e..94ef50367 100644
--- a/Makefile
+++ b/Makefile
@@ -71,7 +71,9 @@ SRCS_COMMON-$(CONFIG_VF_LAVFI)      +=  libmpcodecs/vf_lavfi.c
 SRCS_COMMON-$(FFMPEG_A)              += libmpcodecs/vf_fspp.c           \
                                         libmpcodecs/vf_qp.c             \
                                         libmpcodecs/vf_spp.c            \
-                                        libmpcodecs/vf_uspp.c           \
+
+# needs update for missing coded_frame
+#libmpcodecs/vf_uspp.c           \

 SRCS_COMMON-$(FREETYPE)              += sub/font_load_ft.c
 SRCS_COMMON-$(FTP)                   += stream/stream_ftp.c
diff --git a/av_helpers.c b/av_helpers.c
index 2d543b314..a4e245a19 100644
--- a/av_helpers.c
+++ b/av_helpers.c
@@ -20,6 +20,7 @@

 #include "libavcodec/avcodec.h"
 #include "libavformat/avformat.h"
+#include "libavutil/intreadwrite.h"
 #include "mp_msg.h"
 #include "av_helpers.h"
 #include "libaf/reorder_ch.h"
@@ -165,3 +166,93 @@ int lavc_encode_audio(AVCodecContext *ctx, void *src, int src_len, void *dst, in
     }
     return 0;
 }
+
+#define MERGE_MARKER 0x8c4d9d108e25e9feULL
+
+static void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
+{
+    memcpy(*b, src, size);
+    *b += size;
+}
+
+int mp_packet_merge_side_data(AVPacket *pkt){
+    if(pkt->side_data_elems){
+        AVBufferRef *buf;
+        int i;
+        uint8_t *p;
+        uint64_t size= pkt->size + 8LL + AV_INPUT_BUFFER_PADDING_SIZE;
+        AVPacket old= *pkt;
+        for (i=0; i<old.side_data_elems; i++) {
+            size += old.side_data[i].size + 5LL;
+        }
+        if (size > INT_MAX)
+            return AVERROR(EINVAL);
+        buf = av_buffer_alloc(size);
+        if (!buf)
+            return AVERROR(ENOMEM);
+        pkt->buf = buf;
+        pkt->data = p = buf->data;
+        pkt->size = size - AV_INPUT_BUFFER_PADDING_SIZE;
+        bytestream_put_buffer(&p, old.data, old.size);
+        for (i=old.side_data_elems-1; i>=0; i--) {
+            bytestream_put_buffer(&p, old.side_data[i].data, old.side_data[i].size);
+            AV_WB32(p, old.side_data[i].size);
+            p += 4;
+            *p++ = old.side_data[i].type | ((i==old.side_data_elems-1)*128);
+        }
+        AV_WB64(p, MERGE_MARKER);
+        p += 8;
+        memset(p, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+        av_packet_unref(&old);
+        pkt->side_data_elems = 0;
+        pkt->side_data = NULL;
+        return 1;
+    }
+    return 0;
+}
+
+int mp_packet_split_side_data(AVPacket *pkt){
+    if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == MERGE_MARKER){
+        int i;
+        unsigned int size;
+        uint8_t *p;
+
+        p = pkt->data + pkt->size - 8 - 5;
+        for (i=1; ; i++){
+            size = AV_RB32(p);
+            if (size>INT_MAX - 5 || p - pkt->data < size)
+                return 0;
+            if (p[4]&128)
+                break;
+            if (p - pkt->data < size + 5)
+                return 0;
+            p-= size+5;
+        }
+
+        if (i > AV_PKT_DATA_NB)
+            return AVERROR(ERANGE);
+
+        pkt->side_data = av_malloc_array(i, sizeof(*pkt->side_data));
+        if (!pkt->side_data)
+            return AVERROR(ENOMEM);
+
+        p= pkt->data + pkt->size - 8 - 5;
+        for (i=0; ; i++){
+            size= AV_RB32(p);
+            pkt->side_data[i].data = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
+            pkt->side_data[i].size = size;
+            pkt->side_data[i].type = p[4]&127;
+            if (!pkt->side_data[i].data)
+                return AVERROR(ENOMEM);
+            memcpy(pkt->side_data[i].data, p-size, size);
+            pkt->size -= size + 5;
+            if(p[4]&128)
+                break;
+            p-= size+5;
+        }
+        pkt->size -= 8;
+        pkt->side_data_elems = i+1;
+        return 1;
+    }
+    return 0;
+}
diff --git a/av_helpers.h b/av_helpers.h
index 9c8321305..5bef2aa63 100644
--- a/av_helpers.h
+++ b/av_helpers.h
@@ -22,9 +22,13 @@
 #define MPLAYER_AV_HELPERS_H

 struct AVCodecContext;
+struct AVFrame;
+struct AVPacket;

 void init_avcodec(void);
 void init_avformat(void);
 int lavc_encode_audio(struct AVCodecContext *ctx, void *src, int src_len, void *dst, int dst_len);
+int mp_packet_merge_side_data(struct AVPacket *pkt);
+int mp_packet_split_side_data(struct AVPacket *pkt);

 #endif /* MPLAYER_AV_HELPERS_H */
diff --git a/libmpcodecs/ad_spdif.c b/libmpcodecs/ad_spdif.c
index 8ee472429..d49e4f51b 100644
--- a/libmpcodecs/ad_spdif.c
+++ b/libmpcodecs/ad_spdif.c
@@ -126,7 +126,7 @@ static int init(sh_audio_t *sh)
     lavf_ctx->start_time = AV_NOPTS_VALUE;
     for (i = 0; fmt_id_type[i].name; i++) {
         if (!strcmp(codec_idx2str(sh->codec->dll_idx), fmt_id_type[i].name)) {
-            lavf_ctx->streams[0]->codec->codec_id = fmt_id_type[i].id;
+            lavf_ctx->streams[0]->codecpar->codec_id = fmt_id_type[i].id;
             break;
         }
     }
@@ -161,7 +161,7 @@ static int init(sh_audio_t *sh)
     }
     sh->ds->buffer_pos -= in_size;

-    switch (lavf_ctx->streams[0]->codec->codec_id) {
+    switch (lavf_ctx->streams[0]->codecpar->codec_id) {
     case AV_CODEC_ID_AAC:
         spdif_ctx->iec61937_packet_size = 16384;
         sh->sample_format               = AF_FORMAT_IEC61937_LE;
diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c
index cb23d07b4..6e30c51f6 100644
--- a/libmpcodecs/vd_ffmpeg.c
+++ b/libmpcodecs/vd_ffmpeg.c
@@ -902,7 +902,7 @@ static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){
     pkt.size = len;
     // Necessary to decode e.g. CorePNG and ZeroCodec correctly
     pkt.flags = (sh->ds->flags & 1) ? AV_PKT_FLAG_KEY : 0;
-    av_packet_split_side_data(&pkt);
+    mp_packet_split_side_data(&pkt);
     if (av_packet_get_side_data(&pkt, AV_PKT_DATA_PALETTE, NULL))
         ctx->palette_sent = 1;
     if (!ctx->palette_sent && sh->bih && sh->bih->biBitCount <= 8) {
@@ -977,6 +977,8 @@ static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){

         // average MB quantizer
         {
+// TODO: still possible in new FFmpeg API?
+#if 0
             int x, y;
             int w = ((avctx->width  << lavc_param_lowres)+15) >> 4;
             int h = ((avctx->height << lavc_param_lowres)+15) >> 4;
@@ -989,6 +991,7 @@ static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){
                 q += qstride;
             }
             quality /= w * h;
+#endif
         }

         all_len+=len;
@@ -1079,7 +1082,8 @@ static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){
         swap_palette(mpi->planes[1]);
 #endif
 /* to comfirm with newer lavc style */
-    mpi->qscale = av_frame_get_qp_table(pic, &mpi->qstride, &mpi->qscale_type);
+// TODO: still possible in new FFmpeg API?
+//    mpi->qscale = av_frame_get_qp_table(pic, &mpi->qstride, &mpi->qscale_type);
     mpi->pict_type=pic->pict_type;
     mpi->fields = MP_IMGFIELD_ORDERED;
     if(pic->interlaced_frame) mpi->fields |= MP_IMGFIELD_INTERLACED;
diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c
index 563632cb9..f4f172a76 100644
--- a/libmpcodecs/vf.c
+++ b/libmpcodecs/vf.c
@@ -197,7 +197,7 @@ static const vf_info_t* const filter_list[]={
     &vf_info_hue,
 #ifdef CONFIG_FFMPEG_A
     &vf_info_spp,
-    &vf_info_uspp,
+//    &vf_info_uspp, // TODO: does not currently build
     &vf_info_fspp,
     &vf_info_qp,
 //    &vf_info_mcdeint, //TODO: vf_mcdeint is deactivated because it doesn't build after latest FFmpeg major bumps
diff --git a/libmpcodecs/vf_lavc.c b/libmpcodecs/vf_lavc.c
index 9acd695d7..c5252a8f0 100644
--- a/libmpcodecs/vf_lavc.c
+++ b/libmpcodecs/vf_lavc.c
@@ -33,12 +33,12 @@


 struct vf_priv_s {
-    unsigned char* outbuf;
-    int outbuf_size;
     AVCodecContext* context;
     AVFrame* pic;
-    AVCodec* codec;
+    const AVCodec* codec;
     vo_mpegpes_t pes;
+    AVPacket *pkt;
+    int pkt_has_ref;
 };

 #define lavc_venc_context (*vf->priv->context)
@@ -69,10 +69,7 @@ static int config(struct vf_instance *vf,
 	}
     }

-    free(vf->priv->outbuf);
-
-    vf->priv->outbuf_size=10000+width*height;  // must be enough!
-    vf->priv->outbuf = malloc(vf->priv->outbuf_size);
+    if (vf->priv->pkt_has_ref) av_packet_unref(vf->priv->pkt);

     if (avcodec_open2(&lavc_venc_context, vf->priv->codec, NULL) != 0) {
 	mp_msg(MSGT_MENCODER,MSGL_ERR,MSGTR_CantOpenCodec);
@@ -84,10 +81,9 @@ static int config(struct vf_instance *vf,

 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double endpts){
     mp_image_t* dmpi;
-    int out_size;
     AVFrame *pic= vf->priv->pic;
-    int ret, got_pkt;
-    AVPacket pkt;
+    AVPacket *pkt = vf->priv->pkt;
+    int ret;

     pic->data[0]=mpi->planes[0];
     pic->data[1]=mpi->planes[1];
@@ -96,21 +92,21 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts, double
     pic->linesize[1]=mpi->stride[1];
     pic->linesize[2]=mpi->stride[2];

-    av_init_packet(&pkt);
-    pkt.data = vf->priv->outbuf;
-    pkt.size = vf->priv->outbuf_size;
-    ret = avcodec_encode_video2(&lavc_venc_context, &pkt, pic, &got_pkt);
+    if (vf->priv->pkt_has_ref) av_packet_unref(pkt);
+    ret = avcodec_send_frame(&lavc_venc_context, pic);
+    if (ret >= 0) {
+        ret = avcodec_receive_packet(&lavc_venc_context, pkt);
+    }
+    vf->priv->pkt_has_ref = ret >= 0;

-    if(ret<=0) return 1;
-    if(!got_pkt) return 1;
-    out_size =  pkt.size;
+    if(ret<0) return 1;

     dmpi=vf_get_image(vf->next,IMGFMT_MPEGPES,
 	MP_IMGTYPE_EXPORT, 0,
 	mpi->w, mpi->h);

-    vf->priv->pes.data=vf->priv->outbuf;
-    vf->priv->pes.size=out_size;
+    vf->priv->pes.data=pkt->data;
+    vf->priv->pes.size=pkt->size;
     vf->priv->pes.id=0x1E0;
     vf->priv->pes.timestamp=-1; // dunno

@@ -151,6 +147,7 @@ static int vf_open(vf_instance_t *vf, char *args){

     vf->priv->context=avcodec_alloc_context3(vf->priv->codec);
     vf->priv->pic = av_frame_alloc();
+    vf->priv->pkt = av_packet_alloc();

     // TODO: parse args ->
     if(args) sscanf(args, "%d:%f", &p_quality, &p_fps);
diff --git a/libmpcodecs/vf_screenshot.c b/libmpcodecs/vf_screenshot.c
index 9aafac3a2..e8b87fa91 100644
--- a/libmpcodecs/vf_screenshot.c
+++ b/libmpcodecs/vf_screenshot.c
@@ -49,10 +49,9 @@ struct vf_priv_s {
     int shot, store_slices;
     int dw, dh;
     AVFrame *pic;
+    AVPacket *pkt;
     struct SwsContext *ctx;
     AVCodecContext *avctx;
-    uint8_t *outbuffer;
-    int outbuffer_size;
 };

 //===========================================================================//
@@ -75,7 +74,6 @@ static int config(struct vf_instance *vf,
     vf->priv->ctx=sws_getContextFromCmdLine(width, height, outfmt,
                                  d_width, d_height, IMGFMT_RGB24);

-    av_fast_malloc(&vf->priv->outbuffer, &vf->priv->outbuffer_size, d_width * d_height * 3 * 2);
     if (!vf->priv->avctx) {
         vf->priv->avctx = avcodec_alloc_context3(NULL);
         vf->priv->avctx->pix_fmt = AV_PIX_FMT_RGB24;
@@ -106,17 +104,21 @@ static void write_png(struct vf_priv_s *priv)
 {
     char *fname = priv->fname;
     FILE * fp;
-    AVPacket pkt;
-    int res, got_pkt;
+    AVPacket *pkt = priv->pkt;
+    int res;

-    av_init_packet(&pkt);
-    pkt.data = priv->outbuffer;
-    pkt.size = priv->outbuffer_size;
     priv->pic->width = priv->avctx->width;
     priv->pic->height = priv->avctx->height;
     priv->pic->format = priv->avctx->pix_fmt;
-    res = avcodec_encode_video2(priv->avctx, &pkt, priv->pic, &got_pkt);
-    if (res < 0 || !got_pkt || pkt.size <= 0) {
+    res = avcodec_send_frame(priv->avctx, priv->pic);
+    if (res >= 0) {
+        res = avcodec_receive_packet(priv->avctx, pkt);
+        if (res == AVERROR(EAGAIN)) {
+            avcodec_send_frame(priv->avctx, NULL);
+            res = avcodec_receive_packet(priv->avctx, pkt);
+        }
+    }
+    if (res < 0 || pkt->size <= 0) {
         mp_msg(MSGT_VFILTER,MSGL_ERR,"\nFailed to encode screenshot %s!\n", fname);
         return;
     }
@@ -127,7 +129,8 @@ static void write_png(struct vf_priv_s *priv)
         return;
     }

-    fwrite(priv->outbuffer, pkt.size, 1, fp);
+    fwrite(pkt->data, pkt->size, 1, fp);
+    av_packet_unref(pkt);

     fclose (fp);
     mp_msg(MSGT_VFILTER,MSGL_INFO,"*** screenshot '%s' ***\n",priv->fname);
@@ -281,7 +284,7 @@ static void uninit(vf_instance_t *vf)
     if(vf->priv->ctx) sws_freeContext(vf->priv->ctx);
     av_freep(&vf->priv->pic->data[0]);
     av_frame_free(&vf->priv->pic);
-    av_freep(&vf->priv->outbuffer);
+    av_packet_free(&vf->priv->pkt);
     free(vf->priv->prefix);
     free(vf->priv);
 }
@@ -298,8 +301,8 @@ static int vf_open(vf_instance_t *vf, char *args)
     vf->uninit=uninit;
     vf->priv = calloc(1, sizeof(struct vf_priv_s));
     vf->priv->pic = av_frame_alloc();
+    vf->priv->pkt = av_packet_alloc();
     vf->priv->prefix = strdup(args ? args : "shot");
-    avcodec_register_all();
     if (!avcodec_find_encoder(AV_CODEC_ID_PNG)) {
         mp_msg(MSGT_VFILTER, MSGL_FATAL, "Could not find libavcodec PNG encoder\n");
         return 0;
diff --git a/libmpdemux/demux_lavf.c b/libmpdemux/demux_lavf.c
index d3e6e31ae..db18726db 100644
--- a/libmpdemux/demux_lavf.c
+++ b/libmpdemux/demux_lavf.c
@@ -68,7 +68,7 @@ const m_option_t lavfdopts_conf[] = {
 #define BIO_BUFFER_SIZE 32768

 typedef struct lavf_priv {
-    AVInputFormat *avif;
+    const AVInputFormat *avif;
     AVFormatContext *avfc;
     AVIOContext *pb;
     int audio_streams;
@@ -366,7 +366,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
             if (demuxer->audio->id != i)
                 st->discard= AVDISCARD_ALL;
             if (priv->audio_streams == 0) {
-                int rg_size;
+                size_t rg_size;
                 AVReplayGain *rg = (AVReplayGain*)av_stream_get_side_data(st, AV_PKT_DATA_REPLAYGAIN, &rg_size);
                 if (rg && rg_size >= sizeof(*rg)) {
                     priv->r_gain = rg->track_gain / 10000;
@@ -420,9 +420,12 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
             if (st->time_base.den) { /* if container has time_base, use that */
                 sh_video->video.dwRate= st->time_base.den;
                 sh_video->video.dwScale= st->time_base.num;
+#if 0
             } else {
+                // not available in latest FFmpeg API, ok to just remove?
                 sh_video->video.dwRate= st->codec->time_base.den;
                 sh_video->video.dwScale= st->codec->time_base.num;
+#endif
             }
             sh_video->fps=av_q2d(st->r_frame_rate);
             sh_video->frametime=1/av_q2d(st->r_frame_rate);
@@ -527,7 +530,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i) {
             st->discard= AVDISCARD_ALL;
     }
     if (stream_type) {
-        AVCodec *avc = avcodec_find_decoder(codec->codec_id);
+        const AVCodec *avc = avcodec_find_decoder(codec->codec_id);
         const char *codec_name = avc ? avc->name : "unknown";
         if (!avc && *stream_type == 's' && demuxer->s_streams[i])
             codec_name = sh_sub_type2str(((sh_sub_t *)demuxer->s_streams[i])->type);
@@ -707,7 +710,7 @@ static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){
         }
         sh = ds->sh;
         if (sh && sh->bih) {
-            int size = 0;
+            size_t size = 0;
             const uint8_t *pal = av_packet_get_side_data(&pkt, AV_PKT_DATA_PALETTE, &size);
             if (pal && size)
                 memcpy(((uint8_t *)sh->bih) + sh->bih->biSize, pal, FFMIN(size, 1024));
@@ -721,7 +724,7 @@ static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){
         return 1;
     }

-        av_packet_merge_side_data(&pkt);
+        mp_packet_merge_side_data(&pkt);
         dp=new_demux_packet(pkt.size);
         memcpy(dp->buffer, pkt.data, pkt.size);

diff --git a/sub/av_sub.c b/sub/av_sub.c
index aa95202e5..fcb98a078 100644
--- a/sub/av_sub.c
+++ b/sub/av_sub.c
@@ -43,9 +43,9 @@ static void avsub_to_spudec(AVSubtitleRect **rects, int num_rects,

     if (num_rects == 1) {
         spudec_set_paletted(vo_spudec,
-                            rects[0]->pict.data[0],
-                            rects[0]->pict.linesize[0],
-                            rects[0]->pict.data[1],
+                            rects[0]->data[0],
+                            rects[0]->linesize[0],
+                            rects[0]->data[1],
                             rects[0]->x,
                             rects[0]->y,
                             rects[0]->w,
@@ -66,9 +66,9 @@ static void avsub_to_spudec(AVSubtitleRect **rects, int num_rects,
     spudec_packet_clear(packet);
     for (i = 0; i < num_rects; i++)
         spudec_packet_fill(packet,
-                           rects[i]->pict.data[0],
-                           rects[i]->pict.linesize[0],
-                           rects[i]->pict.data[1],
+                           rects[i]->data[0],
+                           rects[i]->linesize[0],
+                           rects[i]->data[1],
                            rects[i]->x - xmin,
                            rects[i]->y - ymin,
                            rects[i]->w,
@@ -105,7 +105,7 @@ int decode_avsub(struct sh_sub *sh, uint8_t **data, int *size,
     pkt.size = *size;
     pkt.pts = *pts * 1000;
     if (*pts != MP_NOPTS_VALUE && *endpts != MP_NOPTS_VALUE)
-        pkt.convergence_duration = (*endpts - *pts) * 1000;
+        pkt.duration = (*endpts - *pts) * 1000;
     if (!ctx) {
         AVCodec *sub_codec;
         init_avcodec();
--
2.31.1



More information about the MPlayer-dev-eng mailing list