Merge commit '246da0b13551b1f80f067e4f258e5bd691f5ab33'
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 14 Jan 2013 12:59:09 +0000 (13:59 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 14 Jan 2013 13:00:21 +0000 (14:00 +0100)
* commit '246da0b13551b1f80f067e4f258e5bd691f5ab33':
  v4l2: avoid pointless indirection.
  vdpau: Add VC-1 decoding via hwaccel infrastructure
  vdpau: Add H.264 decoding via hwaccel infrastructure

Conflicts:
configure
libavcodec/Makefile
libavcodec/version.h
libavdevice/v4l2.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
configure
libavcodec/Makefile
libavcodec/allcodecs.c
libavcodec/vdpau_h264.c
libavcodec/vdpau_vc1.c
libavcodec/version.h
libavdevice/v4l2.c

diff --cc configure
+++ b/configure
@@@ -1788,10 -1606,9 +1788,11 @@@ h264_crystalhd_decoder_select="crystalh
  h264_dxva2_hwaccel_deps="dxva2api_h"
  h264_dxva2_hwaccel_select="dxva2 h264_decoder"
  h264_vaapi_hwaccel_select="vaapi h264_decoder"
 +h264_vda_decoder_select="vda h264_parser h264_decoder"
 +h264_vda_hwaccel_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
  h264_vda_hwaccel_select="vda h264_decoder"
  h264_vdpau_decoder_select="vdpau h264_decoder"
+ h264_vdpau_hwaccel_select="vdpau h264_decoder"
  mpeg_vdpau_decoder_select="vdpau mpegvideo_decoder"
  mpeg1_vdpau_decoder_select="vdpau mpeg1video_decoder"
  mpeg1_vdpau_hwaccel_select="vdpau mpeg1video_decoder"
@@@ -1811,7 -1623,7 +1812,8 @@@ vc1_dxva2_hwaccel_deps="dxva2api_h
  vc1_dxva2_hwaccel_select="dxva2 vc1_decoder"
  vc1_vaapi_hwaccel_select="vaapi vc1_decoder"
  vc1_vdpau_decoder_select="vdpau vc1_decoder"
+ vc1_vdpau_hwaccel_select="vdpau vc1_decoder"
 +wmv3_crystalhd_decoder_select="crystalhd"
  wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
  wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
  wmv3_vdpau_decoder_select="vc1_vdpau_decoder"
@@@ -228,7 -199,7 +228,8 @@@ OBJS-$(CONFIG_H264_DECODER)            
  OBJS-$(CONFIG_H264_DXVA2_HWACCEL)      += dxva2_h264.o
  OBJS-$(CONFIG_H264_VAAPI_HWACCEL)      += vaapi_h264.o
  OBJS-$(CONFIG_H264_VDA_HWACCEL)        += vda_h264.o
 +OBJS-$(CONFIG_H264_VDA_DECODER)        += vda_h264_dec.o
+ OBJS-$(CONFIG_H264_VDPAU_HWACCEL)      += vdpau_h264.o
  OBJS-$(CONFIG_HUFFYUV_DECODER)         += huffyuv.o huffyuvdec.o
  OBJS-$(CONFIG_HUFFYUV_ENCODER)         += huffyuv.o huffyuvenc.o
  OBJS-$(CONFIG_IAC_DECODER)             += imc.o
Simple merge
index 0000000,09b7ad5..cbe6dee
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,196 +1,196 @@@
 - * This file is part of Libav.
+ /*
+  * MPEG-4 Part 10 / AVC / H.264 HW decode acceleration through VDPAU
+  *
+  * Copyright (c) 2008 NVIDIA
+  * Copyright (c) 2013 Rémi Denis-Courmont
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software Foundation,
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software Foundation,
+  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include <vdpau/vdpau.h>
+ #include "avcodec.h"
+ #include "h264.h"
+ #include "vdpau.h"
+ #include "vdpau_internal.h"
+ static int32_t h264_foc(int foc)
+ {
+     if (foc == INT_MAX)
+         foc = 0;
+     return foc;
+ }
+ static void vdpau_h264_clear_rf(VdpReferenceFrameH264 *rf)
+ {
+     rf->surface             = VDP_INVALID_HANDLE;
+     rf->is_long_term        = VDP_FALSE;
+     rf->top_is_reference    = VDP_FALSE;
+     rf->bottom_is_reference = VDP_FALSE;
+     rf->field_order_cnt[0]  = 0;
+     rf->field_order_cnt[1]  = 0;
+     rf->frame_idx           = 0;
+ }
+ static void vdpau_h264_set_rf(VdpReferenceFrameH264 *rf, Picture *pic,
+                               int pic_structure)
+ {
+     VdpVideoSurface surface = ff_vdpau_get_surface_id(pic);
+     if (pic_structure == 0)
+         pic_structure = pic->f.reference;
+     rf->surface             = surface;
+     rf->is_long_term        = pic->f.reference && pic->long_ref;
+     rf->top_is_reference    = (pic_structure & PICT_TOP_FIELD)    != 0;
+     rf->bottom_is_reference = (pic_structure & PICT_BOTTOM_FIELD) != 0;
+     rf->field_order_cnt[0]  = h264_foc(pic->field_poc[0]);
+     rf->field_order_cnt[1]  = h264_foc(pic->field_poc[1]);
+     rf->frame_idx           = pic->long_ref ? pic->pic_id : pic->frame_num;
+ }
+ static void vdpau_h264_set_reference_frames(AVCodecContext *avctx)
+ {
+     H264Context * const h = avctx->priv_data;
+     AVVDPAUContext *hwctx = avctx->hwaccel_context;
+     VdpPictureInfoH264 *info = &hwctx->info.h264;
+     int list;
+     VdpReferenceFrameH264 *rf = &info->referenceFrames[0];
+ #define H264_RF_COUNT FF_ARRAY_ELEMS(info->referenceFrames)
+     for (list = 0; list < 2; ++list) {
+         Picture **lp = list ? h->long_ref : h->short_ref;
+         int i, ls    = list ? 16          : h->short_ref_count;
+         for (i = 0; i < ls; ++i) {
+             Picture *pic = lp[i];
+             VdpReferenceFrameH264 *rf2;
+             VdpVideoSurface surface_ref;
+             int pic_frame_idx;
+             if (!pic || !pic->f.reference)
+                 continue;
+             pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
+             surface_ref = ff_vdpau_get_surface_id(pic);
+             rf2 = &info->referenceFrames[0];
+             while (rf2 != rf) {
+                 if ((rf2->surface      == surface_ref)   &&
+                     (rf2->is_long_term == pic->long_ref) &&
+                     (rf2->frame_idx    == pic_frame_idx))
+                     break;
+                 ++rf2;
+             }
+             if (rf2 != rf) {
+                 rf2->top_is_reference    |= (pic->f.reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
+                 rf2->bottom_is_reference |= (pic->f.reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
+                 continue;
+             }
+             if (rf >= &info->referenceFrames[H264_RF_COUNT])
+                 continue;
+             vdpau_h264_set_rf(rf, pic, pic->f.reference);
+             ++rf;
+         }
+     }
+     for (; rf < &info->referenceFrames[H264_RF_COUNT]; ++rf)
+         vdpau_h264_clear_rf(rf);
+ }
+ static int vdpau_h264_start_frame(AVCodecContext *avctx,
+                                   const uint8_t *buffer, uint32_t size)
+ {
+     H264Context * const h = avctx->priv_data;
+     AVVDPAUContext *hwctx = avctx->hwaccel_context;
+     MpegEncContext * const s = &h->s;
+     VdpPictureInfoH264 *info = &hwctx->info.h264;
+     Picture *pic = s->current_picture_ptr;
+     /* init VdpPictureInfoH264 */
+     info->slice_count                            = 0;
+     info->field_order_cnt[0]                     = h264_foc(pic->field_poc[0]);
+     info->field_order_cnt[1]                     = h264_foc(pic->field_poc[1]);
+     info->is_reference                           = h->nal_ref_idc != 0;
+     info->frame_num                              = h->frame_num;
+     info->field_pic_flag                         = s->picture_structure != PICT_FRAME;
+     info->bottom_field_flag                      = s->picture_structure == PICT_BOTTOM_FIELD;
+     info->num_ref_frames                         = h->sps.ref_frame_count;
+     info->mb_adaptive_frame_field_flag           = h->sps.mb_aff && !info->field_pic_flag;
+     info->constrained_intra_pred_flag            = h->pps.constrained_intra_pred;
+     info->weighted_pred_flag                     = h->pps.weighted_pred;
+     info->weighted_bipred_idc                    = h->pps.weighted_bipred_idc;
+     info->frame_mbs_only_flag                    = h->sps.frame_mbs_only_flag;
+     info->transform_8x8_mode_flag                = h->pps.transform_8x8_mode;
+     info->chroma_qp_index_offset                 = h->pps.chroma_qp_index_offset[0];
+     info->second_chroma_qp_index_offset          = h->pps.chroma_qp_index_offset[1];
+     info->pic_init_qp_minus26                    = h->pps.init_qp - 26;
+     info->num_ref_idx_l0_active_minus1           = h->pps.ref_count[0] - 1;
+     info->num_ref_idx_l1_active_minus1           = h->pps.ref_count[1] - 1;
+     info->log2_max_frame_num_minus4              = h->sps.log2_max_frame_num - 4;
+     info->pic_order_cnt_type                     = h->sps.poc_type;
+     info->log2_max_pic_order_cnt_lsb_minus4      = h->sps.poc_type ? 0 : h->sps.log2_max_poc_lsb - 4;
+     info->delta_pic_order_always_zero_flag       = h->sps.delta_pic_order_always_zero_flag;
+     info->direct_8x8_inference_flag              = h->sps.direct_8x8_inference_flag;
+     info->entropy_coding_mode_flag               = h->pps.cabac;
+     info->pic_order_present_flag                 = h->pps.pic_order_present;
+     info->deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;
+     info->redundant_pic_cnt_present_flag         = h->pps.redundant_pic_cnt_present;
+     memcpy(info->scaling_lists_4x4, h->pps.scaling_matrix4,
+            sizeof(info->scaling_lists_4x4));
+     memcpy(info->scaling_lists_8x8[0], h->pps.scaling_matrix8[0],
+            sizeof(info->scaling_lists_8x8[0]));
+     memcpy(info->scaling_lists_8x8[1], h->pps.scaling_matrix8[3],
+            sizeof(info->scaling_lists_8x8[1]));
+     vdpau_h264_set_reference_frames(avctx);
+     return ff_vdpau_common_start_frame(avctx, buffer, size);
+ }
+ static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 };
+ static int vdpau_h264_decode_slice(AVCodecContext *avctx,
+                                    const uint8_t *buffer, uint32_t size)
+ {
+     AVVDPAUContext *hwctx = avctx->hwaccel_context;
+     int val;
+     val = ff_vdpau_add_buffer(avctx, start_code_prefix, 3);
+     if (val)
+         return val;
+     val = ff_vdpau_add_buffer(avctx, buffer, size);
+     if (val)
+         return val;
+     hwctx->info.h264.slice_count++;
+     return 0;
+ }
+ AVHWAccel ff_h264_vdpau_hwaccel = {
+     .name           = "h264_vdpau",
+     .type           = AVMEDIA_TYPE_VIDEO,
+     .id             = AV_CODEC_ID_H264,
+     .pix_fmt        = AV_PIX_FMT_VDPAU,
+     .start_frame    = vdpau_h264_start_frame,
+     .end_frame      = ff_vdpau_common_end_frame,
+     .decode_slice   = vdpau_h264_decode_slice,
+ };
index 0000000,638c07a..7c75243
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,128 +1,128 @@@
 - * This file is part of Libav.
+ /*
+  * VC-1 decode acceleration through VDPAU
+  *
+  * Copyright (c) 2008 NVIDIA
+  * Copyright (c) 2013 Rémi Denis-Courmont
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software Foundation,
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software Foundation,
+  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include <vdpau/vdpau.h>
+ #include "avcodec.h"
+ #include "vc1.h"
+ #include "vdpau.h"
+ #include "vdpau_internal.h"
+ static int vdpau_vc1_start_frame(AVCodecContext *avctx,
+                                  const uint8_t *buffer, uint32_t size)
+ {
+     VC1Context * const v  = avctx->priv_data;
+     AVVDPAUContext *hwctx = avctx->hwaccel_context;
+     MpegEncContext * const s = &v->s;
+     VdpPictureInfoVC1 *info = &hwctx->info.vc1;
+     VdpVideoSurface ref;
+     /*  fill LvPictureInfoVC1 struct */
+     info->forward_reference  = VDP_INVALID_HANDLE;
+     info->backward_reference = VDP_INVALID_HANDLE;
+     switch (s->pict_type) {
+     case AV_PICTURE_TYPE_B:
+         ref = ff_vdpau_get_surface_id(&s->next_picture);
+         assert(ref != VDP_INVALID_HANDLE);
+         info->backward_reference = ref;
+         /* fall-through */
+     case AV_PICTURE_TYPE_P:
+         ref = ff_vdpau_get_surface_id(&s->last_picture);
+         assert(ref != VDP_INVALID_HANDLE);
+         info->forward_reference  = ref;
+     }
+     info->slice_count       = 0;
+     if (v->bi_type)
+         info->picture_type  = 4;
+     else
+         info->picture_type  = s->pict_type - 1 + s->pict_type / 3;
+     info->frame_coding_mode = v->fcm;
+     info->postprocflag      = v->postprocflag;
+     info->pulldown          = v->broadcast;
+     info->interlace         = v->interlace;
+     info->tfcntrflag        = v->tfcntrflag;
+     info->finterpflag       = v->finterpflag;
+     info->psf               = v->psf;
+     info->dquant            = v->dquant;
+     info->panscan_flag      = v->panscanflag;
+     info->refdist_flag      = v->refdist_flag;
+     info->quantizer         = v->quantizer_mode;
+     info->extended_mv       = v->extended_mv;
+     info->extended_dmv      = v->extended_dmv;
+     info->overlap           = v->overlap;
+     info->vstransform       = v->vstransform;
+     info->loopfilter        = v->s.loop_filter;
+     info->fastuvmc          = v->fastuvmc;
+     info->range_mapy_flag   = v->range_mapy_flag;
+     info->range_mapy        = v->range_mapy;
+     info->range_mapuv_flag  = v->range_mapuv_flag;
+     info->range_mapuv       = v->range_mapuv;
+     /* Specific to simple/main profile only */
+     info->multires          = v->multires;
+     info->syncmarker        = v->s.resync_marker;
+     info->rangered          = v->rangered | (v->rangeredfrm << 1);
+     info->maxbframes        = v->s.max_b_frames;
+     info->deblockEnable     = v->postprocflag & 1;
+     info->pquant            = v->pq;
+     return ff_vdpau_common_start_frame(avctx, buffer, size);
+ }
+ static int vdpau_vc1_decode_slice(AVCodecContext *avctx,
+                                   const uint8_t *buffer, uint32_t size)
+ {
+     AVVDPAUContext *hwctx = avctx->hwaccel_context;
+     int val;
+     val = ff_vdpau_add_buffer(avctx, buffer, size);
+     if (val < 0)
+         return val;
+     hwctx->info.vc1.slice_count++;
+     return 0;
+ }
+ #if CONFIG_WMV3_VDPAU_HWACCEL
+ AVHWAccel ff_wmv3_vdpau_hwaccel = {
+     .name           = "wm3_vdpau",
+     .type           = AVMEDIA_TYPE_VIDEO,
+     .id             = AV_CODEC_ID_WMV3,
+     .pix_fmt        = AV_PIX_FMT_VDPAU,
+     .start_frame    = vdpau_vc1_start_frame,
+     .end_frame      = ff_vdpau_common_end_frame,
+     .decode_slice   = vdpau_vc1_decode_slice,
+ };
+ #endif
+ AVHWAccel ff_vc1_vdpau_hwaccel = {
+     .name           = "vc1_vdpau",
+     .type           = AVMEDIA_TYPE_VIDEO,
+     .id             = AV_CODEC_ID_VC1,
+     .pix_fmt        = AV_PIX_FMT_VDPAU,
+     .start_frame    = vdpau_vc1_start_frame,
+     .end_frame      = ff_vdpau_common_end_frame,
+     .decode_slice   = vdpau_vc1_decode_slice,
+ };
   * Libavcodec version macros.
   */
  
 +#include "libavutil/avutil.h"
 +
  #define LIBAVCODEC_VERSION_MAJOR 54
- #define LIBAVCODEC_VERSION_MINOR 88
 -#define LIBAVCODEC_VERSION_MINOR 40
 -#define LIBAVCODEC_VERSION_MICRO  0
++#define LIBAVCODEC_VERSION_MINOR 89
 +#define LIBAVCODEC_VERSION_MICRO 100
  
  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                 LIBAVCODEC_VERSION_MINOR, \
@@@ -826,11 -730,10 +820,10 @@@ static int v4l2_read_header(AVFormatCon
          av_log(s1, AV_LOG_VERBOSE,
                 "Querying the device for the current frame size\n");
          fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 -        if (ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
 +        if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
              av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
                     strerror(errno));
-             res = AVERROR(errno);
-             goto out;
+             return AVERROR(errno);
          }
  
          s->width  = fmt.fmt.pix.width;
      if (desired_format == 0) {
          av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
                 "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);
 -        close(s->fd);
 +        v4l2_close(s->fd);
  
-         res = AVERROR(EIO);
-         goto out;
+         return AVERROR(EIO);
      }
 -
 -    if ((res = av_image_check_size(s->width, s->height, 0, s1) < 0))
 +    if ((res = av_image_check_size(s->width, s->height, 0, s1)) < 0)
-         goto out;
+         return res;
  
      s->frame_format = desired_format;
  
 -    if ((res = v4l2_set_parameters(s1) < 0))
 +    if ((res = v4l2_set_parameters(s1)) < 0)
-         goto out;
+         return res;
  
      st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
      s->frame_size =
  
      if ((res = mmap_init(s1)) ||
          (res = mmap_start(s1)) < 0) {
 -        close(s->fd);
 +        v4l2_close(s->fd);
-         goto out;
+         return res;
      }
  
      s->top_field_first = first_field(s->fd);