[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