svn commit: r427753 - in head/multimedia/tvheadend: . files

Jan Beich jbeich at FreeBSD.org
Sun Dec 4 02:02:27 UTC 2016


Author: jbeich
Date: Sun Dec  4 02:02:25 2016
New Revision: 427753
URL: https://svnweb.freebsd.org/changeset/ports/427753

Log:
  multimedia/tvheadend: unbreak with ffmpeg 3.x
  
  src/plumbing/transcoding.c:27:10: fatal error: 'libavutil/audioconvert.h' file not found
   #include <libavutil/audioconvert.h>
            ^
  src/plumbing/transcoding.c:1064:30: error: use of undeclared identifier 'PIX_FMT_YUV420P'; did you
        mean 'AV_PIX_FMT_YUV420P'?
        octx->pix_fmt        = PIX_FMT_YUV420P;
                               ^~~~~~~~~~~~~~~
                               AV_PIX_FMT_YUV420P
  /usr/local/include/libavutil/pixfmt.h:62:5: note: 'AV_PIX_FMT_YUV420P' declared here
      AV_PIX_FMT_YUV420P,   ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
      ^
  src/plumbing/transcoding.c:1092:30: error: use of undeclared identifier 'PIX_FMT_YUV420P'; did you
        mean 'AV_PIX_FMT_YUV420P'?
        octx->pix_fmt        = PIX_FMT_YUV420P;
                               ^~~~~~~~~~~~~~~
                               AV_PIX_FMT_YUV420P
  /usr/local/include/libavutil/pixfmt.h:62:5: note: 'AV_PIX_FMT_YUV420P' declared here
      AV_PIX_FMT_YUV420P,   ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
      ^
  src/plumbing/transcoding.c:1123:30: error: use of undeclared identifier 'PIX_FMT_YUV420P'; did you
        mean 'AV_PIX_FMT_YUV420P'?
        octx->pix_fmt        = PIX_FMT_YUV420P;
                               ^~~~~~~~~~~~~~~
                               AV_PIX_FMT_YUV420P
  /usr/local/include/libavutil/pixfmt.h:62:5: note: 'AV_PIX_FMT_YUV420P' declared here
      AV_PIX_FMT_YUV420P,   ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
      ^
  
  build.freebsd/src/plumbing/transcoding.o: In function `transcoder_input':
  src/plumbing/transcoding.c:(.text+0x559): undefined reference to `avcodec_alloc_frame'
  src/plumbing/transcoding.c:(.text+0x56a): undefined reference to `avcodec_alloc_frame'
  src/plumbing/transcoding.c:(.text+0x57f): undefined reference to `avcodec_get_frame_defaults'
  src/plumbing/transcoding.c:(.text+0x58a): undefined reference to `avcodec_get_frame_defaults'
  build.freebsd/src/plumbing/transcoding.o: In function `transcoder_stream_video':
  src/plumbing/transcoding.c:(.text+0x1904): undefined reference to `avpicture_deinterlace'
  cc: error: linker command failed with exit code 1 (use -v to see invocation)
  
  PR:		214815
  Reported by:	antoine (via exp-run)
  Obtained from:	upstream
  Approved by:	decke (maintainer)

Added:
  head/multimedia/tvheadend/files/patch-ffmpeg30   (contents, props changed)
Modified:
  head/multimedia/tvheadend/Makefile   (contents, props changed)

Modified: head/multimedia/tvheadend/Makefile
==============================================================================
--- head/multimedia/tvheadend/Makefile	Sun Dec  4 01:56:50 2016	(r427752)
+++ head/multimedia/tvheadend/Makefile	Sun Dec  4 02:02:25 2016	(r427753)
@@ -4,7 +4,7 @@
 PORTNAME=	tvheadend
 PORTVERSION=	4.0.8
 DISTVERSIONPREFIX=	v
-PORTREVISION=	1
+PORTREVISION=	2
 CATEGORIES=	multimedia
 
 MAINTAINER=	decke at FreeBSD.org

Added: head/multimedia/tvheadend/files/patch-ffmpeg30
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/multimedia/tvheadend/files/patch-ffmpeg30	Sun Dec  4 02:02:25 2016	(r427753)
@@ -0,0 +1,425 @@
+https://github.com/tvheadend/tvheadend/commit/ea02889c149e3d2b80dcaed3d9ad976145bb92b0
+https://github.com/tvheadend/tvheadend/commit/c63371c8bf51928a6c965bdf17dd73555b7b9d54
+
+--- Makefile.orig	2015-12-16 17:33:33 UTC
++++ Makefile
+@@ -60,7 +60,7 @@ CFLAGS  += -I${ROOTDIR}/libav_static/bui
+ LDFLAGS_FFDIR = ${ROOTDIR}/libav_static/build/ffmpeg/lib
+ LDFLAGS += ${LDFLAGS_FFDIR}/libavresample.a
+ LDFLAGS += ${LDFLAGS_FFDIR}/libswresample.a
+-LDFLAGS += ${LDFLAGS_FFDIR}/libswscale.a
++LDFLAGS += ${LDFLAGS_FFDIR}/libavfilter.a
+ LDFLAGS += ${LDFLAGS_FFDIR}/libavutil.a
+ LDFLAGS += ${LDFLAGS_FFDIR}/libavformat.a
+ LDFLAGS += ${LDFLAGS_FFDIR}/libavcodec.a
+--- Makefile.ffmpeg.orig	2015-12-16 17:33:33 UTC
++++ Makefile.ffmpeg
+@@ -60,7 +60,7 @@ FFMPEG_URL      = http://ffmpeg.org/rele
+ FFMPEG_SHA1     = 65470c9b967485f72f81758a7bad44cf7a1763db
+ 
+ EXTLIBS         = libx264 libvorbis libvpx
+-COMPONENTS      = avutil avformat avcodec swresample swscale avresample
++COMPONENTS      = avutil avformat avcodec swresample avfilter avresample
+ PROTOCOLS       = file
+ DECODERS        = mpeg2video mp2 ac3 eac3 h264 h264_vdpau aac aac_latm vorbis libvorbis
+ ENCODERS        = mpeg2video mp2 libx264 libvpx_vp8 libvpx_vp9 aac libaacplus vorbis libvorbis
+--- configure.orig	2015-12-16 17:33:33 UTC
++++ configure
+@@ -395,7 +395,7 @@ else
+         has_libav=false
+       fi
+ 
+-      if $has_libav && ! check_pkg libswscale ">=2.3.100"; then
++      if $has_libav && ! check_pkg libavfilter ">=4.0.0"; then
+         has_libav=false
+       fi
+ 
+@@ -421,7 +421,7 @@ else
+         has_libav=false
+       fi
+ 
+-      if $has_libav && ! check_pkg libswscale ">=2.1.2"; then
++      if $has_libav && ! check_pkg libavfilter ">=4.0.0"; then
+         has_libav=false
+       fi
+ 
+--- src/libav.c.orig	2015-12-16 17:33:33 UTC
++++ src/libav.c
+@@ -186,4 +186,5 @@ libav_init(void)
+   av_log_set_callback(libav_log_callback);
+   av_log_set_level(AV_LOG_VERBOSE);
+   av_register_all();
++  avfilter_register_all();
+ }
+--- src/libav.h.orig	2015-12-16 17:33:33 UTC
++++ src/libav.h
+@@ -21,6 +21,7 @@
+ 
+ 
+ #include <libavformat/avformat.h>
++#include <libavfilter/avfilter.h>
+ #include "tvheadend.h"
+ 
+ /*
+--- src/plumbing/transcoding.c.orig	2015-12-16 17:33:33 UTC
++++ src/plumbing/transcoding.c
+@@ -19,12 +19,14 @@
+ #include <unistd.h>
+ #include <libavformat/avformat.h>
+ #include <libavcodec/avcodec.h>
+-#include <libswscale/swscale.h>
++#include <libavfilter/avfiltergraph.h>
++#include <libavfilter/buffersink.h>
++#include <libavfilter/buffersrc.h>
++#include <libavutil/opt.h>
+ #include <libavresample/avresample.h>
+ #include <libavutil/opt.h>
+ #include <libavutil/audio_fifo.h>
+ #include <libavutil/dict.h>
+-#include <libavutil/audioconvert.h>
+ 
+ #if LIBAVUTIL_VERSION_MICRO >= 100 /* FFMPEG */
+ #define USING_FFMPEG 1
+@@ -91,9 +93,12 @@ typedef struct video_stream {
+   AVCodec                   *vid_ocodec;
+ 
+   AVFrame                   *vid_dec_frame;
+-  struct SwsContext         *vid_scaler;
+   AVFrame                   *vid_enc_frame;
+ 
++  AVFilterGraph             *flt_graph;
++  AVFilterContext           *flt_bufsrcctx;
++  AVFilterContext           *flt_bufsinkctx;
++
+   int16_t                    vid_width;
+   int16_t                    vid_height;
+ 
+@@ -952,6 +957,114 @@ send_video_packet(transcoder_t *t, trans
+ 
+ }
+ 
++/* create a simple deinterlacer-scaler video filter chain */
++static int
++create_video_filter(video_stream_t *vs, transcoder_t *t,
++                    AVCodecContext *ictx, AVCodecContext *octx)
++{
++  AVFilterInOut *flt_inputs, *flt_outputs;
++  AVFilter *flt_bufsrc, *flt_bufsink;
++  char opt[128];
++  int err;
++
++  err = 1;
++  flt_inputs = flt_outputs = NULL;
++  flt_bufsrc = flt_bufsink = NULL;
++
++  if (vs->flt_graph)
++    avfilter_graph_free(&vs->flt_graph);
++
++  vs->flt_graph = avfilter_graph_alloc();
++  if (!vs->flt_graph)
++    return err;
++
++  flt_inputs = avfilter_inout_alloc();
++  if (!flt_inputs)
++    goto out_err;
++
++  flt_outputs = avfilter_inout_alloc();
++  if (!flt_outputs)
++    goto out_err;
++
++  flt_bufsrc = avfilter_get_by_name("buffer");
++  flt_bufsink = avfilter_get_by_name("buffersink");
++  if (!flt_bufsrc || !flt_bufsink) {
++    tvherror("transcode", "%04X: libav default buffers unknown", shortid(t));
++    goto out_err;
++  }
++
++  memset(opt, 0, sizeof(opt));
++  snprintf(opt, sizeof(opt), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
++           ictx->width,
++           ictx->height,
++           ictx->pix_fmt,
++           ictx->time_base.num,
++           ictx->time_base.den,
++           ictx->sample_aspect_ratio.num,
++           ictx->sample_aspect_ratio.den);
++
++  err = avfilter_graph_create_filter(&vs->flt_bufsrcctx, flt_bufsrc, "in",
++                                     opt, NULL, vs->flt_graph);
++  if (err < 0) {
++    tvherror("transcode", "%04X: fltchain IN init error", shortid(t));
++    goto out_err;
++  }
++
++  err = avfilter_graph_create_filter(&vs->flt_bufsinkctx, flt_bufsink,
++                                     "out", NULL, NULL, vs->flt_graph);
++  if (err < 0) {
++    tvherror("transcode", "%04X: fltchain OUT init error", shortid(t));
++    goto out_err;
++  }
++
++  flt_outputs->name = av_strdup("in");
++  flt_outputs->filter_ctx = vs->flt_bufsrcctx;
++  flt_outputs->pad_idx = 0;
++  flt_outputs->next = NULL;
++  flt_inputs->name = av_strdup("out");
++  flt_inputs->filter_ctx = vs->flt_bufsinkctx;
++  flt_inputs->pad_idx = 0;
++  flt_inputs->next = NULL;
++
++  /* add filters: yadif to deinterlace and a scaler */
++  memset(opt, 0, sizeof(opt));
++  snprintf(opt, sizeof(opt), "yadif,scale=%dx%d",
++           octx->width,
++           octx->height);
++  err = avfilter_graph_parse_ptr(vs->flt_graph,
++                                 opt,
++                                 &flt_inputs,
++                                 &flt_outputs,
++                                 NULL);
++  if (err < 0) {
++    tvherror("transcode", "%04X: failed to init filter chain", shortid(t));
++    goto out_err;
++  }
++
++  err = avfilter_graph_config(vs->flt_graph, NULL);
++  if (err < 0) {
++    tvherror("transcode", "%04X: failed to config filter chain", shortid(t));
++    goto out_err;
++  }
++
++  avfilter_inout_free(&flt_inputs);
++  avfilter_inout_free(&flt_outputs);
++
++  return 0;  /* all OK */
++
++out_err:
++  if (flt_inputs)
++    avfilter_inout_free(&flt_inputs);
++  if (flt_outputs)
++    avfilter_inout_free(&flt_outputs);
++  if (vs->flt_graph) {
++    avfilter_graph_free(&vs->flt_graph);
++    vs->flt_graph = NULL;
++  }
++
++  return err;
++}
++
+ /**
+  *
+  */
+@@ -962,9 +1075,7 @@ transcoder_stream_video(transcoder_t *t,
+   AVCodecContext *ictx, *octx;
+   AVDictionary *opts;
+   AVPacket packet, packet2;
+-  AVPicture deint_pic;
+-  uint8_t *buf, *deint;
+-  int length, len, ret, got_picture, got_output, got_ref;
++  int length, ret, got_picture, got_output, got_ref;
+   video_stream_t *vs = (video_stream_t*)ts;
+   streaming_message_t *sm;
+   th_pkt_t *pkt2;
+@@ -980,7 +1091,6 @@ transcoder_stream_video(transcoder_t *t,
+   icodec = vs->vid_icodec;
+   ocodec = vs->vid_ocodec;
+ 
+-  buf = deint = NULL;
+   opts = NULL;
+ 
+   got_ref = 0;
+@@ -1061,7 +1171,7 @@ transcoder_stream_video(transcoder_t *t,
+     switch (ts->ts_type) {
+     case SCT_MPEG2VIDEO:
+       octx->codec_id       = AV_CODEC_ID_MPEG2VIDEO;
+-      octx->pix_fmt        = PIX_FMT_YUV420P;
++      octx->pix_fmt        = AV_PIX_FMT_YUV420P;
+       octx->flags         |= CODEC_FLAG_GLOBAL_HEADER;
+ 
+       // Default settings for quantizer. Best quality unless changed by the streaming profile.
+@@ -1089,7 +1199,7 @@ transcoder_stream_video(transcoder_t *t,
+ 
+     case SCT_VP8:
+       octx->codec_id       = AV_CODEC_ID_VP8;
+-      octx->pix_fmt        = PIX_FMT_YUV420P;
++      octx->pix_fmt        = AV_PIX_FMT_YUV420P;
+ 
+       av_dict_set(&opts, "quality", "realtime", 0);
+ 
+@@ -1120,7 +1230,7 @@ transcoder_stream_video(transcoder_t *t,
+ 
+     case SCT_H264:
+       octx->codec_id       = AV_CODEC_ID_H264;
+-      octx->pix_fmt        = PIX_FMT_YUV420P;
++      octx->pix_fmt        = AV_PIX_FMT_YUV420P;
+       octx->flags          |= CODEC_FLAG_GLOBAL_HEADER;
+ 
+       // Qscale difference between I-frames and P-frames. 
+@@ -1177,79 +1287,53 @@ transcoder_stream_video(transcoder_t *t,
+       transcoder_stream_invalidate(ts);
+       goto cleanup;
+     }
+-  }
+-
+-  len = avpicture_get_size(ictx->pix_fmt, ictx->width, ictx->height);
+-  deint = av_malloc(len);
+ 
+-  avpicture_fill(&deint_pic,
+-		 deint, 
+-		 ictx->pix_fmt, 
+-		 ictx->width, 
+-		 ictx->height);
+-
+-  if (avpicture_deinterlace(&deint_pic,
+-			    (AVPicture *)vs->vid_dec_frame,
+-			    ictx->pix_fmt,
+-			    ictx->width,
+-			    ictx->height) < 0) {
+-    tvherror("transcode", "%04X: Cannot deinterlace frame", shortid(t));
+-    transcoder_stream_invalidate(ts);
+-    goto cleanup;
++    if (create_video_filter(vs, t, ictx, octx)) {
++      tvherror("transcode", "%04X: Video filter creation failed",
++               shortid(t));
++      transcoder_stream_invalidate(ts);
++      goto cleanup;
++    }
+   }
+ 
+-  len = avpicture_get_size(octx->pix_fmt, octx->width, octx->height);
+-  buf = av_malloc(len + FF_INPUT_BUFFER_PADDING_SIZE);
+-  memset(buf, 0, len);
+-
+-  avpicture_fill((AVPicture *)vs->vid_enc_frame, 
+-                 buf, 
+-                 octx->pix_fmt,
+-                 octx->width, 
+-                 octx->height);
+- 
+-  vs->vid_scaler = sws_getCachedContext(vs->vid_scaler,
+-				    ictx->width,
+-				    ictx->height,
+-				    ictx->pix_fmt,
+-				    octx->width,
+-				    octx->height,
+-				    octx->pix_fmt,
+-				    1,
+-				    NULL,
+-				    NULL,
+-				    NULL);
+- 
+-  if (sws_scale(vs->vid_scaler, 
+-		(const uint8_t * const*)deint_pic.data, 
+-		deint_pic.linesize, 
+-		0, 
+-		ictx->height, 
+-		vs->vid_enc_frame->data, 
+-		vs->vid_enc_frame->linesize) < 0) {
+-    tvherror("transcode", "%04X: Cannot scale frame", shortid(t));
++  /* push decoded frame into filter chain */
++  if (av_buffersrc_add_frame(vs->flt_bufsrcctx, vs->vid_dec_frame) < 0) {
++    tvherror("transcode", "%04X: filter input error", shortid(t));
+     transcoder_stream_invalidate(ts);
+     goto cleanup;
+   }
+ 
+-  vs->vid_enc_frame->format  = octx->pix_fmt;
+-  vs->vid_enc_frame->width   = octx->width;
+-  vs->vid_enc_frame->height  = octx->height;
++  /* and pull out a filtered frame */
++  while (1) {
++	ret = av_buffersink_get_frame(vs->flt_bufsinkctx, vs->vid_enc_frame);
++	if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
++		break;
++	if (ret < 0) {
++		tvherror("transcode", "%04X: filter output error", shortid(t));
++		transcoder_stream_invalidate(ts);
++		goto cleanup;
++	}
+ 
+-  vs->vid_enc_frame->pkt_pts = vs->vid_dec_frame->pkt_pts;
+-  vs->vid_enc_frame->pkt_dts = vs->vid_dec_frame->pkt_dts;
++	vs->vid_enc_frame->format  = octx->pix_fmt;
++	vs->vid_enc_frame->width   = octx->width;
++	vs->vid_enc_frame->height  = octx->height;
+ 
+-  if (vs->vid_dec_frame->reordered_opaque != AV_NOPTS_VALUE)
+-    vs->vid_enc_frame->pts = vs->vid_dec_frame->reordered_opaque;
++	vs->vid_enc_frame->pkt_pts = vs->vid_dec_frame->pkt_pts;
++	vs->vid_enc_frame->pkt_dts = vs->vid_dec_frame->pkt_dts;
+ 
+-  else if (ictx->coded_frame && ictx->coded_frame->pts != AV_NOPTS_VALUE)
+-    vs->vid_enc_frame->pts = vs->vid_dec_frame->pts;
++	if (vs->vid_dec_frame->reordered_opaque != AV_NOPTS_VALUE)
++		vs->vid_enc_frame->pts = vs->vid_dec_frame->reordered_opaque;
+ 
+-  ret = avcodec_encode_video2(octx, &packet2, vs->vid_enc_frame, &got_output);
+-  if (ret < 0) {
+-    tvherror("transcode", "%04X: Error encoding frame", shortid(t));
+-    transcoder_stream_invalidate(ts);
+-    goto cleanup;
++	else if (ictx->coded_frame && ictx->coded_frame->pts != AV_NOPTS_VALUE)
++		vs->vid_enc_frame->pts = vs->vid_dec_frame->pts;
++
++	ret = avcodec_encode_video2(octx, &packet2, vs->vid_enc_frame, &got_output);
++	if (ret < 0) {
++		tvherror("transcode", "%04X: Error encoding frame", shortid(t));
++		transcoder_stream_invalidate(ts);
++		goto cleanup;
++	}
++	av_frame_unref(vs->vid_enc_frame);
+   }
+ 
+   if (got_output)
+@@ -1263,12 +1347,6 @@ transcoder_stream_video(transcoder_t *t,
+ 
+   av_free_packet(&packet);
+ 
+-  if(buf)
+-    av_free(buf);
+-
+-  if(deint)
+-    av_free(deint);
+-
+   if(opts)
+     av_dict_free(&opts);
+ 
+@@ -1548,15 +1626,17 @@ transcoder_destroy_video(transcoder_t *t
+   if(vs->vid_dec_frame)
+     av_free(vs->vid_dec_frame);
+ 
+-  if(vs->vid_scaler)
+-    sws_freeContext(vs->vid_scaler);
+-
+   if(vs->vid_enc_frame)
+     av_free(vs->vid_enc_frame);
+ 
+   if (vs->vid_first_pkt)
+     pkt_ref_dec(vs->vid_first_pkt);
+ 
++  if (vs->flt_graph) {
++    avfilter_graph_free(&vs->flt_graph);
++    vs->flt_graph = NULL;
++  }
++
+   free(ts);
+ }
+ 
+@@ -1603,11 +1683,13 @@ transcoder_init_video(transcoder_t *t, s
+   vs->vid_ictx->thread_count =
+     vs->vid_octx->thread_count = transcoder_thread_count(t, sct);
+ 
+-  vs->vid_dec_frame = avcodec_alloc_frame();
+-  vs->vid_enc_frame = avcodec_alloc_frame();
++  vs->vid_dec_frame = av_frame_alloc();
++  vs->vid_enc_frame = av_frame_alloc();
+ 
+-  avcodec_get_frame_defaults(vs->vid_dec_frame);
+-  avcodec_get_frame_defaults(vs->vid_enc_frame);
++  av_frame_unref(vs->vid_dec_frame);
++  av_frame_unref(vs->vid_enc_frame);
++
++  vs->flt_graph = NULL;		/* allocated in packet processor */
+ 
+   LIST_INSERT_HEAD(&t->t_stream_list, (transcoder_stream_t*)vs, ts_link);
+ 


More information about the svn-ports-head mailing list