On Wed, Feb 27, 2013 at 04:49:07PM +0100, Maxym Dmytrychenko wrote:
> "make checkheaders" is fine for MinGW and MSVC
>
> ---
> libavcodec/qsv.c | 549 ++++++++++++++++++++++++++++++++
> libavcodec/qsv.h | 476 ++++++++++++++++++++++++++++
> libavcodec/qsv_h264.c | 835
> +++++++++++++++++++++++++++++++++++++++++++++++++
> libavcodec/qsv_h264.h | 63 ++++
> 4 files changed, 1923 insertions(+), 0 deletions(-)
> create mode 100644 libavcodec/qsv.c
> create mode 100644 libavcodec/qsv.h
> create mode 100644 libavcodec/qsv_h264.c
> create mode 100644 libavcodec/qsv_h264.h
Why is this patch separate from 2/2? It makes no sense standalone.
> --- /dev/null
> +++ b/libavcodec/qsv.c
> @@ -0,0 +1,549 @@
> +
> +int av_qsv_get_free_encode_task(av_qsv_list *tasks)
> +{
> + int ret = MFX_ERR_NOT_FOUND;
> + int i = 0;
> + if (tasks)
> + for (i = 0; i < av_qsv_list_count(tasks); i++) {
> + av_qsv_task *task = av_qsv_list_item(tasks, i);
> + if (task->stage && task->stage->out.p_sync)
> + if (!(*task->stage->out.p_sync)) {
> + ret = i;
> + break;
> + }
> + }
> + return ret;
You can return i directly instead of breaking out of the loop.
> +int av_qsv_get_free_sync(av_qsv_space *space, av_qsv_context *qsv)
> +{
> + int ret = -1;
> + int counter = 0;
> +
> + while (1) {
> + for (int i = 0; i < space->sync_num; i++)
Don't declare variables inside for statements like this. Some compilers
choke on it. Supposedly also MSVC, so I wonder why you did not stumble
over the problem. You have a new MSVC version that does not trip up?
> + if (!(*(space->p_sync[i])) &&
> !ff_qsv_is_sync_in_pipe(space->p_sync[i], qsv)) {
Break the long line.
> +int av_qsv_get_free_surface(av_qsv_space *space, av_qsv_context *qsv,
> mfxFrameInfo *info, av_qsv_split part)
long line
> + for (int i = from; i < up; i++)
> + if ((!space->p_surfaces[i]->Data.Locked) &&
> !ff_qsv_is_surface_in_pipe(space->p_surfaces[i], qsv)) {
same
> + av_log(NULL, AV_LOG_FATAL,
> + "Have not enough to have %d surface(s) allocated\n", up);
Have not enough .. what?
> +int ff_qsv_is_surface_in_pipe(mfxFrameSurface1 *p_surface, av_qsv_context
> *qsv)
> +{
> + int ret = 0;
> + int a, b;
> + av_qsv_list *list = 0;
> + av_qsv_stage *stage = 0;
> +
> + if (!p_surface)
> + return ret;
> + if (!qsv->pipes)
> + return ret;
Please merge the two if-clauses with ||.
> + for (a = 0; a < av_qsv_list_count(qsv->pipes); a++) {
> + list = av_qsv_list_item(qsv->pipes, a);
> + for (b = 0; b < av_qsv_list_count(list); b++) {
> + stage = av_qsv_list_item(list, b);
> + if (p_surface == stage->out.p_surface ||
> + p_surface == stage->in.p_surface) {
> + return 1;
> + }
> + }
> + }
> + return ret;
> +}
The ret variable is not assigned, so pretty pointless.
> +int ff_qsv_is_sync_in_pipe(mfxSyncPoint *sync, av_qsv_context *qsv)
> +{
> + int ret = 0;
> + int a, b;
> + av_qsv_list *list = 0;
> + av_qsv_stage *stage = 0;
> +
> + if (!sync)
> + return ret;
> + if (!qsv->pipes)
> + return ret;
> +
> + for (a = 0; a < av_qsv_list_count(qsv->pipes); a++) {
> + list = av_qsv_list_item(qsv->pipes, a);
> + for (b = 0; b < av_qsv_list_count(list); b++) {
> + stage = av_qsv_list_item(list, b);
> + if (sync == stage->out.p_sync) {
> + return 1;
> + }
> + }
> + }
> + return ret;
> +}
ditto
> +av_qsv_stage *av_qsv_stage_init(void)
> +{
> + return (av_qsv_stage *)av_mallocz(sizeof(av_qsv_stage));
> +}
pointless void* cast
> +int av_qsv_context_clean(av_qsv_context *qsv)
> +{
> + int is_active = 0;
> + mfxStatus sts = MFX_ERR_NONE;
> +
> + is_active = ff_qsv_atomic_dec(&qsv->is_context_active);
> +
> + // spaces would have to be cleaned on the own,
> + // here we care about the rest, common stuff
> + if (is_active == 0) {
> + if (qsv->dts_seq) {
> + while (av_qsv_list_count(qsv->dts_seq))
> + av_qsv_dts_pop(qsv);
I don't understand the comment - what is "spaces"?
> +void av_qsv_pipe_list_create(av_qsv_list **list, int is_threaded)
> +{
> + if (!*list)
> + *list = av_qsv_list_init(is_threaded);
> +}
Wouldn't it be simpler to pass list as * instead of ** and dereferencing?
> +void av_qsv_pipe_list_clean(av_qsv_list **list)
> +{
> + av_qsv_list *stage;
> + int i = 0;
> + if (*list) {
> + for (i = av_qsv_list_count(*list); i > 0; i--) {
> + stage = av_qsv_list_item(*list, i - 1);
> + av_qsv_flush_stages(*list, &stage);
> + }
> + av_qsv_list_close(list);
> + }
> +}
same
> +void av_qsv_add_stagee(av_qsv_list **list, av_qsv_stage *stage, int
> is_threaded)
> +{
> + if (!*list)
> + *list = av_qsv_list_init(is_threaded);
> + if (*list)
> + av_qsv_list_add(*list, stage);
> +}
same
> +av_qsv_stage *av_qsv_get_by_mask(av_qsv_list *list, int mask, av_qsv_stage
> **prev, av_qsv_list **this_pipe)
long line
> +{
> + av_qsv_list *item = 0;
> + av_qsv_stage *stage = 0;
> + av_qsv_stage *prev_stage = 0;
> + int i = 0;
> + int a = 0;
> + *this_pipe = 0;
> + *prev = 0;
> + for (i = 0; i < av_qsv_list_count(list); i++) {
> + item = av_qsv_list_item(list, i);
> + for (a = 0; a < av_qsv_list_count(item); a++) {
> +}
> +
> +av_qsv_list *av_qsv_pipe_by_stage(av_qsv_list *list, av_qsv_stage *stage)
> +{
> + av_qsv_list *item = 0;
> + av_qsv_stage *cur_stage = 0;
> + int i = 0;
> + int a = 0;
> + for (i = 0; i < av_qsv_list_count(list); i++) {
> + item = av_qsv_list_item(list, i);
> + for (a = 0; a < av_qsv_list_count(item); a++) {
You can skip the first initialization of i and a.
> +// no duplicate of the same value, if end == 0 : working over full length
> +void av_qsv_dts_ordered_insert(av_qsv_context *qsv, int start, int end,
> int64_t dts, int iter)
long line
> +{
> + av_qsv_dts *cur_dts = 0;
> + av_qsv_dts *new_dts = 0;
> + int i = 0;
pointless initialization of i
> +av_qsv_list *av_qsv_list_init(int is_threaded)
> +{
> + av_qsv_list *l = av_mallocz(sizeof(av_qsv_list));
> + if (!l)
> + return 0;
> + l->items = av_mallocz_array(AV_QSV_JOB_SIZE_DEFAULT, sizeof(void *));
> + if (!l->items) {
> + av_free(l);
> + return 0;
> + }
> + l->items_alloc = AV_QSV_JOB_SIZE_DEFAULT;
> +
> +#if HAVE_THREADS
> + if (is_threaded) {
> + l->mutex = av_mallocz(sizeof(pthread_mutex_t));
> + if (!l->mutex) {
> + av_free(l->items);
> + av_free(l);
> + return 0;
> + }
> + if (l->mutex)
> + pthread_mutex_init(l->mutex, NULL);
> + } else
> +#endif
> + l->mutex = 0;
> + return l;
> +}
You should return NULL, not 0 for pointers.
> +int av_qsv_list_add(av_qsv_list *l, void *p)
> +{
> + int pos = -1;
> + if (!p) {
> + return pos;
> + }
> +#if HAVE_THREADS
> + if (l->mutex)
> + pthread_mutex_lock(l->mutex);
> +#endif
> + if (l->items_count == l->items_alloc) {
> + l->items_alloc += AV_QSV_JOB_SIZE_DEFAULT;
> + l->items = av_realloc(l->items, l->items_alloc * sizeof(void
> *));
> + if (!l->items)
> + return pos;
> + }
> +
> + l->items[l->items_count] = p;
> + pos = (l->items_count);
> + (l->items_count)++;
pointless ()
> +void av_qsv_list_close(av_qsv_list **_l)
> +{
> + av_qsv_list *l = *_l;
> +
> +#if HAVE_THREADS
> + if (l->mutex)
> + pthread_mutex_destroy(&l->mutex);
> +#endif
> +
> + av_free(l->items);
> + av_free(l);
> +
> + *_l = NULL;
> +}
Avoid names starting with underscores; they are reserved at the file level
or completely. Just "list" would be better here I think.
> +int av_is_qsv_available(mfxIMPL impl, mfxVersion *ver)
> +{
> + mfxStatus sts = MFX_ERR_NONE;
> + mfxSession mfx_session;
> +
> + memset(&mfx_session, 0, sizeof(mfxSession));
Initialize mfx_session to { 0 } instead.
> --- /dev/null
> +++ b/libavcodec/qsv.h
> @@ -0,0 +1,476 @@
> +/*
> + * Copyright (C) 2013 Intel Corporation. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + * - Redistributions of source code must retain the above copyright notice,
> + * this list of conditions and the following disclaimer.
> + * - Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the documentation
> + * and/or other materials provided with the distribution.
> + * - Neither the name of Intel Corporation nor the names of its contributors
> + * may be used to endorse or promote products derived from this software
> + * without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
> + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
> + * IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
> + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + */
nit: Remove the empty line.
> +
> +#ifndef AVCODEC_QSV_H
> +#define AVCODEC_QSV_H
> +
> +/**
> + * @file
> + * @ingroup lavc_codec_hwaccel_qsv
> + * Common header for QSV/MediaSDK acceleration
> + */
> +
> +/**
> + * @defgroup lavc_codec_hwaccel_qsv QSV/MediaSDK based Decode/Encode and
> Video Pre-Processing/VPP
> + * @ingroup lavc_codec_hwaccel
> + *
> + * As Intel Quick Sync Video (QSV) can decode/preprocess/encode with
> hardware
> + * acceleration
> + *
> + * Supported features:
> + * - IO Pattern:
> + * - Opaque memory: MFX_IOPATTERN_OUT_OPAQUE_MEMORY // Video memory is
> + * MFX_IMPL_HARDWARE or MFX_IMPL_AUTO and runtime
> support,
> + * otherwise: System Memory
> + * - System memory: MFX_IOPATTERN_OUT_SYSTEM_MEMORY
> + * - Allocators:
> + * - default allocator for System memory: MFX_MEMTYPE_SYSTEM_MEMORY
> + * - details:
> + * implementation as "per frame"
> + *
> + * TODO list:
> + * - format AV_PIX_FMT_QSV_MPEG2
> + * - format AV_PIX_FMT_QSV_VC1
> + * - IO Pattern:
> + * - VIDEO_MEMORY // MFX_IOPATTERN_OUT_VIDEO_MEMORY
> + * - Allocators:
> + * - Video memory: MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET /
> + * MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET
> + *
> + * Note av_qsv_config struct required to fill in via
> + * AVCodecContext.hwaccel_context
> + *
> + * As per frame, note AVFrame.data[2] (qsv_atom) used for frame atom id,
> + * data/linesize should be used together with SYSTEM_MEMORY and tested
> + *
> + * Note: Compilation would require:
> + * - Intel MediaSDK headers, Full SDK is avaialble from the original web
> site:
> + *
> http://software.intel.com/en-us/vcsource/tools/media-SDK
> + * and
> + * - Final application has to link against Intel MediaSDK dispatcher,
> available
> + * at MediaSDK as well
> + *
> + * Target OS: as per available dispatcher and driver support
> + *
> + * Implementation details:
> + * Provided struct av_qsv_context contain several struct av_qsv_space(s)
> for decode,
> + * VPP and encode.
> + * av_qsv_space just contain needed environment for the appropriate action.
> + * Based on this - pipeline (see pipes) will be build to pass details such
> as
> + * mfxFrameSurface1* and mfxSyncPoint* from one action to the next.
> + *
> + * Resources re-usage (av_qsv_flush_stages), if resource_free ||
> usage_threaded option:
> + * av_qsv_context *qsv = (av_qsv_context *)video_codec_ctx->priv_data;
> + * av_qsv_list *pipe = (av_qsv_list *)video_frame->data[2];
> + * av_qsv_flush_stages( qsv->pipes, &pipe );
> + *
> + * DTS re-usage, if dts_need option:
> + * av_qsv_dts_pop(qsv);
> + *
> + * for video,DX9/11 memory it has to be Unlock'ed as well
> + *
> + * Implementation is thread aware and uses synchronization point(s) from
> MediaSDK
> + * as per configuration.
> + *
> + * For the details of MediaSDK usage and options available - please refer
> to the
> + * available documentation at MediaSDK.
> + *
> + * Feature set used from MSDK is defined by AV_QSV_MSDK_VERSION_MAJOR and
> + * AV_QSV_MSDK_VERSION_MINOR
> + *
> + * @{
> + */
> +
> +#include <stdint.h>
> +#include <string.h>
> +
> +#ifdef HAVE_AV_CONFIG_H
> +#include "config.h"
> +#endif
> +#if HAVE_THREADS
> +// atomic ops
> +#if defined (__GNUC__)
> +#define ff_qsv_atomic_inc(ptr) __sync_add_and_fetch(ptr, 1)
> +#define ff_qsv_atomic_dec(ptr) __sync_sub_and_fetch(ptr, 1)
> +#elif HAVE_WINDOWS_H // MSVC case
> +#include <windows.h>
> +#define ff_qsv_atomic_inc(ptr) InterlockedIncrement(ptr)
> +#define ff_qsv_atomic_dec(ptr) InterlockedDecrement(ptr)
> +#endif
> +// threading implementation
> +#if HAVE_PTHREADS
> +#include <pthread.h>
> +#elif HAVE_W32THREADS
> +#include "w32pthreads.h"
> +#endif
> +#else
> +#define ff_qsv_atomic_inc(ptr) ((*ptr)++)
> +#define ff_qsv_atomic_dec(ptr) ((*ptr)--)
> +#endif
Once again, with feeling: none of this can be in an installed header.
> +// sleep is defined in milliseconds
> +#define av_qsv_sleep(x) av_usleep((x) * 1000)
> +
> +#define AV_QSV_ZERO_MEMORY(VAR) { memset(&VAR, 0, sizeof(VAR)); }
> +#define AV_QSV_ALIGN32(X) (((mfxU32)((X)+31)) & (~(mfxU32)31))
> +#define AV_QSV_ALIGN16(value) (((value + 15) >> 4) << 4)
> +#ifndef AV_QSV_PRINT_RET_MSG
> +#define AV_QSV_PRINT_RET_MSG(ERR) \
> + { av_log(NULL, AV_LOG_FATAL, \
> + "Error code %d,\t%s\t%d\n", ERR, __FUNCTION__, __LINE__); \
> + }
> +#endif
> +
> +#ifndef AV_QSV_DEBUG_ASSERT
> +#define AV_QSV_DEBUG_ASSERT(x, y) { if ((x)) { av_log(NULL, AV_LOG_FATAL,
> "\nASSERT: %s\n", y); } }
> +#endif
> +
> +#define AV_QSV_CHECK_RESULT(P, X, ERR) { if ((X) > (P)) {
> AV_QSV_PRINT_RET_MSG(ERR); return ERR; } }
> +#define AV_QSV_CHECK_POINTER(P, ERR) { if (!(P)) {
> AV_QSV_PRINT_RET_MSG(ERR); return ERR; } }
> +#define AV_QSV_IGNORE_MFX_STS(P, X) { if ((X) == (P)) { P =
> MFX_ERR_NONE; } }
> +
> +#define AV_QSV_ID_BUFFER MFX_MAKEFOURCC('B', 'U', 'F', 'F')
> +#define AV_QSV_ID_FRAME MFX_MAKEFOURCC('F', 'R', 'M', 'E')
> +
> +#define AV_QSV_SURFACE_NUM 80
> +#define AV_QSV_SYNC_NUM AV_QSV_SURFACE_NUM * 3 / 4
> +#define AV_QSV_BUF_SIZE_DEFAULT 4096 * 2160 * 10
> +#define AV_QSV_JOB_SIZE_DEFAULT 10
> +#define AV_QSV_SYNC_TIME_DEFAULT 10000
> +// see av_qsv_get_free_sync, av_qsv_get_free_surface , 100 if
> usleep(10*1000)(10ms) == 1 sec
> +#define AV_QSV_REPEAT_NUM_DEFAULT 100
> +#define AV_QSV_ASYNC_DEPTH_DEFAULT 4
Why should all of this become exported libav API?
> +// version of MSDK/QSV API currently used
> +#define AV_QSV_MSDK_VERSION_MAJOR 1
> +#define AV_QSV_MSDK_VERSION_MINOR 3
> +
> +typedef enum AV_QSV_STAGE_TYPE {
> +#define AV_QSV_DECODE_MASK 0x001
> + AV_QSV_DECODE = 0x001,
> +
> +#define AV_QSV_VPP_MASK 0x0F0
> + // "Mandatory VPP filter" , might be with "Hint-based VPP filters"
> + AV_QSV_VPP_DEFAULT = 0x010,
> + // "User Modules" etc
> + AV_QSV_VPP_USER = 0x020,
> +
> +#define av_QSV_ENCODE_MASK 0x100
> + AV_QSV_ENCODE = 0x100
> +#define AV_QSV_ANY_MASK 0xFFF
> +} AV_QSV_STAGE_TYPE;
In one case you lowercase the "av" prefix.
Is there a reason not to separate the #defines and the enum?
> +static const uint8_t ff_prefix_code[] = { 0x00, 0x00, 0x00, 0x01 };
A static table in a header is generally not a good idea; it will get
duplicated at each #inclusion.
> +int av_qsv_list_count(av_qsv_list *);
> +int av_qsv_list_add(av_qsv_list *, void *);
> +void av_qsv_list_rem(av_qsv_list *, void *);
> +void av_qsv_list_insert(av_qsv_list *, int, void *);
> +void *av_qsv_list_item(av_qsv_list *, int);
> +void av_qsv_list_close(av_qsv_list **);
Add the parameter names.
> --- /dev/null
> +++ b/libavcodec/qsv_h264.c
> @@ -0,0 +1,835 @@
> +/*
> + * Copyright (C) 2013 Intel Corporation. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + * - Redistributions of source code must retain the above copyright notice,
> + * this list of conditions and the following disclaimer.
> + * - Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the documentation
> + * and/or other materials provided with the distribution.
> + * - Neither the name of Intel Corporation nor the names of its contributors
> + * may be used to endorse or promote products derived from this software
> + * without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
> + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
> + * IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
> + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + */
nit: Drop the empty line.
> +int ff_qsv_dec_init(AVCodecContext *avctx)
> +{
> +
> + memset(&qsv->mfx_session, 0, sizeof(mfxSession));
> + qsv->ver.Major = AV_QSV_MSDK_VERSION_MAJOR;
> + qsv->ver.Minor = AV_QSV_MSDK_VERSION_MINOR;
> +
> + AV_QSV_ZERO_MEMORY(qsv_decode->m_mfxVideoParam);
> + AV_QSV_ZERO_MEMORY(qsv_decode->bs);
Sometimes you use this (IMO) pointless macro, sometimes memset ...
> + sts = MFXVideoDECODE_DecodeHeader(qsv->mfx_session, &qsv_decode->bs,
> + &qsv_decode->m_mfxVideoParam);
> + AV_QSV_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
In libav we do not use such macros to check return values generally.
> + qsv_decode->sync_num = FFMIN(qsv_decode->surface_num, AV_QSV_SYNC_NUM);
> + for (int i = 0; i < qsv_decode->sync_num; i++) {
see above
> +int ff_qsv_decode_init(AVCodecContext *avctx)
init functions should be marked as av_cold.
> +{
> + av_qsv_context *qsv;
> + av_qsv_space *qsv_decode;
> + av_qsv_config **qsv_config_context = (av_qsv_config
> **)&avctx->hwaccel_context;
pointless void* cast
> + } else {
> + if ((*qsv_config_context)->io_pattern !=
> MFX_IOPATTERN_OUT_OPAQUE_MEMORY
> + && (*qsv_config_context)->io_pattern !=
> MFX_IOPATTERN_OUT_SYSTEM_MEMORY) {
nit: Move the && to the previous line.
> + av_log_missing_feature(avctx, "MFX_IOPATTERN_OUT_SYSTEM_MEMORY
> type", 0);
This is about to be replaced with avpriv_report_missing_feature, ETA tomorrow.
> + av_log(avctx, AV_LOG_FATAL, "No QSV allocators found for
> clean up\n");
cleanup
> + for (int i = 0; i < qsv_decode->surface_num; i++)
see above
> +static int qsv_decode_frame(AVCodecContext *avctx, void *data,
> + int *data_size, AVPacket *avpkt)
> +{
> + if (current_size) {
> + while (current_offset <= current_size) {
> + current_nal_size =
> + (current_position[current_offset - 2] << 24 |
> + current_position[current_offset - 1] << 16 |
> + current_position[current_offset] << 8 |
> + current_position[current_offset + 1]) - 1;
> + nal_type = current_position[current_offset + 2] & 0x1F;
> + {
> + frame_length += current_nal_size;
> +
> + memcpy(&qsv_decode->bs.Data[0] +
> + qsv_decode->bs.DataLength +
> + qsv_decode->bs.DataOffset, ff_prefix_code,
> + sizeof(ff_prefix_code));
> + qsv_decode->bs.DataLength += sizeof(ff_prefix_code);
> + memcpy(&qsv_decode->bs.Data[0] +
> + qsv_decode->bs.DataLength +
> + qsv_decode->bs.DataOffset,
> + ¤t_position[current_offset + 2],
> + current_nal_size + 1);
> + qsv_decode->bs.DataLength += current_nal_size + 1;
> + }
Why the block {}?
> + if (qsv_config_context->dts_need) {
> + //not a drain
> + if ((current_size || qsv_decode->bs.DataLength))
pointless ()
> + while (MFX_ERR_NONE <= sts || MFX_ERR_MORE_SURFACE == sts
> + || MFX_WRN_DEVICE_BUSY == sts) {
nit: Move the || to the previous line.
> + // have some results
> + if (MFX_ERR_NONE <= sts && MFX_WRN_DEVICE_BUSY != sts &&
> + MFX_WRN_VIDEO_PARAM_CHANGED != sts) {
> + new_stage->type = AV_QSV_DECODE;
> + new_stage->in.p_bs = input_bs;
> + new_stage->in.p_surface =
> qsv_decode->p_surfaces[surface_idx];
I don't understand the comment.
> +mfxStatus ff_qsv_mem_frame_free(mfxHDL pthis,
> + mfxFrameAllocResponse *response)
> +{
> + mfxU32 i;
> +
> + if (response->mids)
> + for (i = 0; i < response->NumFrameActual; i++)
Why isn't i a plain int or unsigned?
> +mfxStatus ff_qsv_mem_buffer_alloc(mfxHDL pthis, mfxU32 nbytes, mfxU16 type,
> + mfxMemId *mid)
> +{
> + av_qsv_alloc_buffer *bs;
> + mfxU32 header_size;
> + mfxU8 *buffer_ptr;
> +
> + if (!mid)
> + return MFX_ERR_NULL_PTR;
> +
> + if (0 == (type & MFX_MEMTYPE_SYSTEM_MEMORY))
nit: We generally prefer to write ! in such cases:
if (!(type & MFX_MEMTYPE_SYSTEM_MEMORY))
> +AVCodec ff_h264_qsv_decoder = {
> + .name = "h264_qsv",
> + .type = AVMEDIA_TYPE_VIDEO,
> + .id = AV_CODEC_ID_H264,
> + .init = ff_qsv_decode_init,
> + .close = qsv_decode_end,
> + .decode = qsv_decode_frame,
> + .capabilities = CODEC_CAP_DELAY,
> + .flush = qsv_flush_dpb,
> + .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / Intel QSV"),
Make this
NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel QSV
acceleration)"),
to match the VDPAU one.
> --- /dev/null
> +++ b/libavcodec/qsv_h264.h
> @@ -0,0 +1,63 @@
> +/*
> + * Copyright (C) 2013 Intel Corporation. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + * - Redistributions of source code must retain the above copyright notice,
> + * this list of conditions and the following disclaimer.
> + * - Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the documentation
> + * and/or other materials provided with the distribution.
> + * - Neither the name of Intel Corporation nor the names of its contributors
> + * may be used to endorse or promote products derived from this software
> + * without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY EXPRESS OR
> + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
> + * IN NO EVENT SHALL INTEL CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT,
> + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + */
nit: Drop the empty line.
> +int ff_qsv_dec_init(AVCodecContext *);
Please add the parameter name.
> +static int qsv_decode_end(AVCodecContext *avctx);
> +static int qsv_decode_frame(AVCodecContext *avctx, void *data, int
> *data_size, AVPacket *avpkt);
> +static void qsv_flush_dpb(AVCodecContext *avctx);
Why are there static declarations in a header?
> +// Default for SYSTEM MEMORY
> +// as from MFXFrameAllocator
> +mfxStatus ff_qsv_mem_frame_alloc(mfxHDL pthis,
> + mfxFrameAllocRequest *request,
> + mfxFrameAllocResponse *response);
I don't understand the comment.
> +#endif //AVCODEC_QSV_H264_H
nit: #endif /* AVCODEC_QSV_H264_H */
Diego
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel