利用ffmpeg移植到嵌入式计算poc

利用ffmpeg移植到嵌入式计算poc

1、修改 \ffmpeg-3.2.4\libavcodec\hevc.c 下方的函数需要屏蔽一些代码


static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal)
{
    HEVCLocalContext *lc = s->HEVClc;
    GetBitContext *gb    = &lc->gb;
    int ctb_addr_ts, ret;

    *gb              = nal->gb;
    s->nal_unit_type = nal->type;
    s->temporal_id   = nal->temporal_id;

    switch (s->nal_unit_type) {
    case NAL_VPS:
        ret = ff_hevc_decode_nal_vps(gb, s->avctx, &s->ps);
        if (ret < 0)
            goto fail;
        break;
    case NAL_SPS:
        ret = ff_hevc_decode_nal_sps(gb, s->avctx, &s->ps,
                                     s->apply_defdispwin);
        if (ret < 0)
            goto fail;
        break;
    case NAL_PPS:
        ret = ff_hevc_decode_nal_pps(gb, s->avctx, &s->ps);
        if (ret < 0)
            goto fail;
        break;
    case NAL_SEI_PREFIX:
    case NAL_SEI_SUFFIX:
        ret = ff_hevc_decode_nal_sei(s);
        if (ret < 0)
            goto fail;
        break;
    case NAL_TRAIL_R:
    case NAL_TRAIL_N:
    case NAL_TSA_N:
    case NAL_TSA_R:
    case NAL_STSA_N:
    case NAL_STSA_R:
    case NAL_BLA_W_LP:
    case NAL_BLA_W_RADL:
    case NAL_BLA_N_LP:
    case NAL_IDR_W_RADL:
    case NAL_IDR_N_LP:
    case NAL_CRA_NUT:
    case NAL_RADL_N:
    case NAL_RADL_R:
    case NAL_RASL_N:
    case NAL_RASL_R:
        ret = hls_slice_header(s);
        if (ret < 0)
            return ret;

        if (s->max_ra == INT_MAX) {
            if (s->nal_unit_type == NAL_CRA_NUT || IS_BLA(s)) {
                s->max_ra = s->poc;
            } else {
                if (IS_IDR(s))
                    s->max_ra = INT_MIN;
            }
        }

        if ((s->nal_unit_type == NAL_RASL_R || s->nal_unit_type == NAL_RASL_N) &&
            s->poc <= s->max_ra) {
            s->is_decoded = 0;
            break;
        } else {
            if (s->nal_unit_type == NAL_RASL_R && s->poc > s->max_ra)
                s->max_ra = INT_MIN;
        }
        #if 0 //屏蔽下面对片数据的解码,因为在嵌入式软cpu解码能力不够
        if (s->sh.first_slice_in_pic_flag) {
            ret = hevc_frame_start(s);
            if (ret < 0)
                return ret;
        } else if (!s->ref) {
            av_log(s->avctx, AV_LOG_ERROR, "First slice in a frame missing.\n");
            goto fail;
        }

        if (s->nal_unit_type != s->first_nal_type) {
            av_log(s->avctx, AV_LOG_ERROR,
                   "Non-matching NAL types of the VCL NALUs: %d %d\n",
                   s->first_nal_type, s->nal_unit_type);
            return AVERROR_INVALIDDATA;
        }

        if (!s->sh.dependent_slice_segment_flag &&
            s->sh.slice_type != I_SLICE) {
            ret = ff_hevc_slice_rpl(s);
            if (ret < 0) {
                av_log(s->avctx, AV_LOG_WARNING,
                       "Error constructing the reference lists for the current slice.\n");
                goto fail;
            }
        }

        if (s->sh.first_slice_in_pic_flag && s->avctx->hwaccel) {
            ret = s->avctx->hwaccel->start_frame(s->avctx, NULL, 0);
            if (ret < 0)
                goto fail;
        }

        if (s->avctx->hwaccel) {
            ret = s->avctx->hwaccel->decode_slice(s->avctx, nal->raw_data, nal->raw_size);
            if (ret < 0)
                goto fail;
        } else {
            if (s->threads_number > 1 && s->sh.num_entry_point_offsets > 0)
                ctb_addr_ts = hls_slice_data_wpp(s, nal);
            else
                ctb_addr_ts = hls_slice_data(s);
            if (ctb_addr_ts >= (s->ps.sps->ctb_width * s->ps.sps->ctb_height)) {
                s->is_decoded = 1;
            }

            if (ctb_addr_ts < 0) {
                ret = ctb_addr_ts;
                goto fail;
            }
        }
        #endif
        break;
    case NAL_EOS_NUT:
    case NAL_EOB_NUT:
        s->seq_decode = (s->seq_decode + 1) & 0xff;
        s->max_ra     = INT_MAX;
        break;
    case NAL_AUD:
    case NAL_FD_NUT:
        break;
    default:
        av_log(s->avctx, AV_LOG_INFO,
               "Skipping NAL unit %d\n", s->nal_unit_type);
    }

    return 0;
fail:
    if (s->avctx->err_recognition & AV_EF_EXPLODE)
        return ret;
    return 0;
}

2、编译生成静态库
3、获取poc模块(另外增加)

/*
 * Copyright (c) 2001 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/**
 * @file
 * libavcodec API use example.
 *
 * @example decoding_encoding.c
 * Note that libavcodec only handles codecs (MPEG, MPEG-4, etc...),
 * not file formats (AVI, VOB, MP4, MOV, MKV, MXF, FLV, MPEG-TS, MPEG-PS, etc...).
 * See library 'libavformat' for the format handling
 */

#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif


#include <math.h>
#include <libavutil/opt.h>
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/common.h>
#include <libavutil/imgutils.h>
#include <libavutil/mathematics.h>
#include <libavutil/samplefmt.h>
#include <libavcodec/hevc.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct video_decode_h265_calc
{
    AVCodecContext *avctx;
    AVFrame *       frame;
}video_decode_h265_calc_s;

static video_decode_h265_calc_s g_h265;

int video_decode_h265_calc_poc(char * f_buf, int f_len)
{
    int len = 0, got_frame = 0;

    AVPacket avpkt;
    av_init_packet(&avpkt);

    avpkt.size          = f_len;
    avpkt.data          = f_buf;

    int poc = 0;
    while (avpkt.size > 0)
    {
        len = avcodec_decode_video2(g_h265.avctx, g_h265.frame, &got_frame, &avpkt);
        if (len < 0)
        {
            fprintf(stderr, "Error while decoding\n");
            return len;
        }
        if (avpkt.data)
        {
            avpkt.size -= len;
            avpkt.data += len;
        }

        HEVCContext *s = g_h265.avctx->priv_data;
        poc = s->poc;
        //printf("%s %d POC: %d\n", __FUNCTION__, __LINE__, poc);
    }

    return poc;
}


int video_decode_h265_init()
{
    /* register all the codecs */
    avcodec_register_all();

    //av_log_set_level(AV_LOG_DEBUG);

    /* find the MPEG-1 video decoder */
    AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_HEVC);
    if (!codec)
    {
        fprintf(stderr, "Codec not found\n");
        exit(1);
    }

    g_h265.avctx = avcodec_alloc_context3(codec);
    if (!g_h265.avctx)
    {
        fprintf(stderr, "Could not allocate video codec context\n");
        exit(1);
    }

    if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
        g_h265.avctx->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames

    /* open it */
    if (avcodec_open2(g_h265.avctx, codec, NULL) < 0)
    {
        fprintf(stderr, "Could not open codec\n");
        exit(1);
    }

    g_h265.frame = av_frame_alloc();
    if (!g_h265.frame)
    {
        fprintf(stderr, "Could not allocate video frame\n");
        exit(1);
    }

    return 0;
}

int video_decode_h265_exit()
{
    avcodec_close(g_h265.avctx);
    av_free(g_h265.avctx);
    av_frame_free(&g_h265.frame);

    return 0;
}

/*
int main()
{
    return 0;
}
*/


#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FFmpeg是一个开源的跨平台音视频处理库,可以用来处理音频和视频的编码、解码、转码以及流媒体的处理等。移植FFmpeg到ARM架构上,可以使其在具有ARM处理器的设备上运行,例如智能手机、平板电脑和嵌入式系统等。 在移植FFmpeg到ARM上,首先需要进行代码的适配,将代码针对ARM架构进行编译和优化。ARM架构与x86架构有一些差异,所以需要进行一些相关的修改和调整,以确保FFmpeg代码可以在ARM上正常运行。 其次,需要根据ARM平台的特性和资源限制进行配置。ARM架构通常会有不同的版本和各自的特性,因此需要根据具体的ARM平台进行相应的配置,以提供最佳的性能和兼容性。 另外,还需要解决ARM平台上可能存在的一些兼容性问题。由于ARM平台的生态系统和软件环境与x86平台存在差异,在移植过程中可能会遇到一些与硬件、操作系统或其他软件的兼容性问题。需要及时解决这些问题,以确保FFmpeg在ARM上的正常运行。 最后,还可以根据ARM平台的特性,对FFmpeg进行优化和定制,以进一步提升性能。例如,可以针对ARM的 SIMD(Single Instruction, Multiple Data)指令集进行优化,充分利用ARM处理器的并行计算能力。此外,还可以针对ARM平台使用的特定格式或编解码算法进行优化,以提升对这些格式或算法的处理速度和效率。 总之,移植FFmpeg到ARM上是为了在ARM设备上实现音视频处理的功能。这需要进行代码的适配和优化,配置ARM平台的相关参数,并解决可能出现的兼容性问题,以提供高性能和稳定性的音视频处理能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值