利用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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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