diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-05-12 02:34:01 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-05-12 02:44:28 +0200 |
commit | 5460ab73d2e8169c54beda06e7cca762aee84a1f (patch) | |
tree | 8c50adb34c4df34a90cba7bc14edc84fe8bd4f13 | |
parent | 2856332719d8ec182523f7793bb0517aaac68e73 (diff) | |
parent | 1839fafa951308237c4672ffd9a94f927b26eac7 (diff) | |
download | ffmpeg-5460ab73d2e8169c54beda06e7cca762aee84a1f.tar.gz |
Merge commit '1839fafa951308237c4672ffd9a94f927b26eac7'
* commit '1839fafa951308237c4672ffd9a94f927b26eac7':
avconv: Support VDA hwaccel
Conflicts:
Makefile
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | doc/ffmpeg.texi | 3 | ||||
-rw-r--r-- | ffmpeg.h | 2 | ||||
-rw-r--r-- | ffmpeg_opt.c | 3 | ||||
-rw-r--r-- | ffmpeg_vda.c | 134 |
5 files changed, 143 insertions, 0 deletions
@@ -31,6 +31,7 @@ $(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog)-$(CONFIG_OPENCL) += cmdutils_o OBJS-ffmpeg += ffmpeg_opt.o ffmpeg_filter.o OBJS-ffmpeg-$(HAVE_VDPAU_X11) += ffmpeg_vdpau.o OBJS-ffmpeg-$(HAVE_DXVA2_LIB) += ffmpeg_dxva2.o +OBJS-ffmpeg-$(CONFIG_VDA) += ffmpeg_vda.o TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64 HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 05c7d974c3..765b2a7ebc 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -643,6 +643,9 @@ Do not use any hardware acceleration (the default). @item auto Automatically select the hardware acceleration method. +@item vda +Use Apple VDA hardware acceleration. + @item vdpau Use VDPAU (Video Decode and Presentation API for Unix) hardware acceleration. @@ -61,6 +61,7 @@ enum HWAccelID { HWACCEL_AUTO, HWACCEL_VDPAU, HWACCEL_DXVA2, + HWACCEL_VDA, }; typedef struct HWAccel { @@ -514,5 +515,6 @@ int ffmpeg_parse_options(int argc, char **argv); int vdpau_init(AVCodecContext *s); int dxva2_init(AVCodecContext *s); +int vda_init(AVCodecContext *s); #endif /* FFMPEG_H */ diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index 5b6a26abbe..8e3873c807 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -70,6 +70,9 @@ const HWAccel hwaccels[] = { #if HAVE_DXVA2_LIB { "dxva2", dxva2_init, HWACCEL_DXVA2, AV_PIX_FMT_DXVA2_VLD }, #endif +#if CONFIG_VDA + { "vda", vda_init, HWACCEL_VDA, AV_PIX_FMT_VDA }, +#endif { 0 }, }; diff --git a/ffmpeg_vda.c b/ffmpeg_vda.c new file mode 100644 index 0000000000..b9f0975f55 --- /dev/null +++ b/ffmpeg_vda.c @@ -0,0 +1,134 @@ +/* + * This file is part of FFmpeg. + * + * 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. + * + * 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 "libavcodec/avcodec.h" +#include "libavcodec/vda.h" +#include "libavutil/imgutils.h" + +#include "ffmpeg.h" + +typedef struct VDAContext { + AVFrame *tmp_frame; +} VDAContext; + +static int vda_retrieve_data(AVCodecContext *s, AVFrame *frame) +{ + InputStream *ist = s->opaque; + VDAContext *vda = ist->hwaccel_ctx; + CVPixelBufferRef pixbuf = (CVPixelBufferRef)frame->data[3]; + OSType pixel_format = CVPixelBufferGetPixelFormatType(pixbuf); + CVReturn err; + uint8_t *data[4] = { 0 }; + int linesize[4] = { 0 }; + int planes, ret, i; + + av_frame_unref(vda->tmp_frame); + + switch (pixel_format) { + case kCVPixelFormatType_420YpCbCr8Planar: vda->tmp_frame->format = AV_PIX_FMT_YUV420P; break; + case kCVPixelFormatType_422YpCbCr8: vda->tmp_frame->format = AV_PIX_FMT_UYVY422; break; + default: + av_log(NULL, AV_LOG_ERROR, + "Unsupported pixel format: %u\n", pixel_format); + return AVERROR(ENOSYS); + } + + vda->tmp_frame->width = frame->width; + vda->tmp_frame->height = frame->height; + ret = av_frame_get_buffer(vda->tmp_frame, 32); + if (ret < 0) + return ret; + + err = CVPixelBufferLockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly); + if (err != kCVReturnSuccess) { + av_log(NULL, AV_LOG_ERROR, "Error locking the pixel buffer.\n"); + return AVERROR_UNKNOWN; + } + + if (CVPixelBufferIsPlanar(pixbuf)) { + + planes = CVPixelBufferGetPlaneCount(pixbuf); + for (i = 0; i < planes; i++) { + data[i] = CVPixelBufferGetBaseAddressOfPlane(pixbuf, i); + linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(pixbuf, i); + } + } else { + data[0] = CVPixelBufferGetBaseAddress(pixbuf); + linesize[0] = CVPixelBufferGetBytesPerRow(pixbuf); + } + + av_image_copy(vda->tmp_frame->data, vda->tmp_frame->linesize, + data, linesize, vda->tmp_frame->format, + frame->width, frame->height); + + ret = av_frame_copy_props(vda->tmp_frame, frame); + if (ret < 0) + return ret; + + av_frame_unref(frame); + av_frame_move_ref(frame, vda->tmp_frame); + + return 0; +} + +static void vda_uninit(AVCodecContext *s) +{ + InputStream *ist = s->opaque; + VDAContext *vda = ist->hwaccel_ctx; + + ist->hwaccel_uninit = NULL; + ist->hwaccel_retrieve_data = NULL; + + av_frame_free(&vda->tmp_frame); + + av_vda_default_free(s); + av_freep(&ist->hwaccel_ctx); +} + +int vda_init(AVCodecContext *s) +{ + InputStream *ist = s->opaque; + int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR; + VDAContext *vda; + int ret; + + vda = av_mallocz(sizeof(*vda)); + if (!vda) + return AVERROR(ENOMEM); + + ist->hwaccel_ctx = vda; + ist->hwaccel_uninit = vda_uninit; + ist->hwaccel_retrieve_data = vda_retrieve_data; + + vda->tmp_frame = av_frame_alloc(); + if (!vda->tmp_frame) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = av_vda_default_init(s); + if (ret < 0) { + av_log(NULL, loglevel, "Error creating VDA decoder.\n"); + goto fail; + } + + return 0; +fail: + vda_uninit(s); + return ret; +} |