1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * HEVC Annex B format parser 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * Copyright (C) 2012 - 2013 Guillaume Martres 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include "libavutil/common.h" 24cabdff1aSopenharmony_ci 25cabdff1aSopenharmony_ci#include "golomb.h" 26cabdff1aSopenharmony_ci#include "hevc.h" 27cabdff1aSopenharmony_ci#include "hevc_parse.h" 28cabdff1aSopenharmony_ci#include "hevc_ps.h" 29cabdff1aSopenharmony_ci#include "hevc_sei.h" 30cabdff1aSopenharmony_ci#include "h2645_parse.h" 31cabdff1aSopenharmony_ci#include "parser.h" 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci#define START_CODE 0x000001 ///< start_code_prefix_one_3bytes 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_ci#define IS_IRAP_NAL(nal) (nal->type >= 16 && nal->type <= 23) 36cabdff1aSopenharmony_ci#define IS_IDR_NAL(nal) (nal->type == HEVC_NAL_IDR_W_RADL || nal->type == HEVC_NAL_IDR_N_LP) 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_citypedef struct HEVCParserContext { 39cabdff1aSopenharmony_ci ParseContext pc; 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_ci H2645Packet pkt; 42cabdff1aSopenharmony_ci HEVCParamSets ps; 43cabdff1aSopenharmony_ci HEVCSEI sei; 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci int is_avc; 46cabdff1aSopenharmony_ci int nal_length_size; 47cabdff1aSopenharmony_ci int parsed_extradata; 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_ci int poc; 50cabdff1aSopenharmony_ci int pocTid0; 51cabdff1aSopenharmony_ci} HEVCParserContext; 52cabdff1aSopenharmony_ci 53cabdff1aSopenharmony_cistatic int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal, 54cabdff1aSopenharmony_ci AVCodecContext *avctx) 55cabdff1aSopenharmony_ci{ 56cabdff1aSopenharmony_ci HEVCParserContext *ctx = s->priv_data; 57cabdff1aSopenharmony_ci HEVCParamSets *ps = &ctx->ps; 58cabdff1aSopenharmony_ci HEVCSEI *sei = &ctx->sei; 59cabdff1aSopenharmony_ci GetBitContext *gb = &nal->gb; 60cabdff1aSopenharmony_ci const HEVCWindow *ow; 61cabdff1aSopenharmony_ci int i, num = 0, den = 0; 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_ci unsigned int pps_id, first_slice_in_pic_flag, dependent_slice_segment_flag; 64cabdff1aSopenharmony_ci enum HEVCSliceType slice_type; 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_ci first_slice_in_pic_flag = get_bits1(gb); 67cabdff1aSopenharmony_ci s->picture_structure = sei->picture_timing.picture_struct; 68cabdff1aSopenharmony_ci s->field_order = sei->picture_timing.picture_struct; 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci if (IS_IRAP_NAL(nal)) { 71cabdff1aSopenharmony_ci s->key_frame = 1; 72cabdff1aSopenharmony_ci skip_bits1(gb); // no_output_of_prior_pics_flag 73cabdff1aSopenharmony_ci } 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_ci pps_id = get_ue_golomb(gb); 76cabdff1aSopenharmony_ci if (pps_id >= HEVC_MAX_PPS_COUNT || !ps->pps_list[pps_id]) { 77cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id); 78cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 79cabdff1aSopenharmony_ci } 80cabdff1aSopenharmony_ci ps->pps = (HEVCPPS*)ps->pps_list[pps_id]->data; 81cabdff1aSopenharmony_ci 82cabdff1aSopenharmony_ci if (ps->pps->sps_id >= HEVC_MAX_SPS_COUNT || !ps->sps_list[ps->pps->sps_id]) { 83cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", ps->pps->sps_id); 84cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 85cabdff1aSopenharmony_ci } 86cabdff1aSopenharmony_ci if (ps->sps != (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data) { 87cabdff1aSopenharmony_ci ps->sps = (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data; 88cabdff1aSopenharmony_ci ps->vps = (HEVCVPS*)ps->vps_list[ps->sps->vps_id]->data; 89cabdff1aSopenharmony_ci } 90cabdff1aSopenharmony_ci ow = &ps->sps->output_window; 91cabdff1aSopenharmony_ci 92cabdff1aSopenharmony_ci s->coded_width = ps->sps->width; 93cabdff1aSopenharmony_ci s->coded_height = ps->sps->height; 94cabdff1aSopenharmony_ci s->width = ps->sps->width - ow->left_offset - ow->right_offset; 95cabdff1aSopenharmony_ci s->height = ps->sps->height - ow->top_offset - ow->bottom_offset; 96cabdff1aSopenharmony_ci s->format = ps->sps->pix_fmt; 97cabdff1aSopenharmony_ci avctx->profile = ps->sps->ptl.general_ptl.profile_idc; 98cabdff1aSopenharmony_ci avctx->level = ps->sps->ptl.general_ptl.level_idc; 99cabdff1aSopenharmony_ci 100cabdff1aSopenharmony_ci if (ps->vps->vps_timing_info_present_flag) { 101cabdff1aSopenharmony_ci num = ps->vps->vps_num_units_in_tick; 102cabdff1aSopenharmony_ci den = ps->vps->vps_time_scale; 103cabdff1aSopenharmony_ci } else if (ps->sps->vui.vui_timing_info_present_flag) { 104cabdff1aSopenharmony_ci num = ps->sps->vui.vui_num_units_in_tick; 105cabdff1aSopenharmony_ci den = ps->sps->vui.vui_time_scale; 106cabdff1aSopenharmony_ci } 107cabdff1aSopenharmony_ci 108cabdff1aSopenharmony_ci if (num != 0 && den != 0) 109cabdff1aSopenharmony_ci av_reduce(&avctx->framerate.den, &avctx->framerate.num, 110cabdff1aSopenharmony_ci num, den, 1 << 30); 111cabdff1aSopenharmony_ci 112cabdff1aSopenharmony_ci if (!first_slice_in_pic_flag) { 113cabdff1aSopenharmony_ci unsigned int slice_segment_addr; 114cabdff1aSopenharmony_ci int slice_address_length; 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci if (ps->pps->dependent_slice_segments_enabled_flag) 117cabdff1aSopenharmony_ci dependent_slice_segment_flag = get_bits1(gb); 118cabdff1aSopenharmony_ci else 119cabdff1aSopenharmony_ci dependent_slice_segment_flag = 0; 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci slice_address_length = av_ceil_log2_c(ps->sps->ctb_width * 122cabdff1aSopenharmony_ci ps->sps->ctb_height); 123cabdff1aSopenharmony_ci slice_segment_addr = get_bitsz(gb, slice_address_length); 124cabdff1aSopenharmony_ci if (slice_segment_addr >= ps->sps->ctb_width * ps->sps->ctb_height) { 125cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Invalid slice segment address: %u.\n", 126cabdff1aSopenharmony_ci slice_segment_addr); 127cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 128cabdff1aSopenharmony_ci } 129cabdff1aSopenharmony_ci } else 130cabdff1aSopenharmony_ci dependent_slice_segment_flag = 0; 131cabdff1aSopenharmony_ci 132cabdff1aSopenharmony_ci if (dependent_slice_segment_flag) 133cabdff1aSopenharmony_ci return 0; /* break; */ 134cabdff1aSopenharmony_ci 135cabdff1aSopenharmony_ci for (i = 0; i < ps->pps->num_extra_slice_header_bits; i++) 136cabdff1aSopenharmony_ci skip_bits(gb, 1); // slice_reserved_undetermined_flag[] 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ci slice_type = get_ue_golomb_31(gb); 139cabdff1aSopenharmony_ci if (!(slice_type == HEVC_SLICE_I || slice_type == HEVC_SLICE_P || 140cabdff1aSopenharmony_ci slice_type == HEVC_SLICE_B)) { 141cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unknown slice type: %d.\n", 142cabdff1aSopenharmony_ci slice_type); 143cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 144cabdff1aSopenharmony_ci } 145cabdff1aSopenharmony_ci s->pict_type = slice_type == HEVC_SLICE_B ? AV_PICTURE_TYPE_B : 146cabdff1aSopenharmony_ci slice_type == HEVC_SLICE_P ? AV_PICTURE_TYPE_P : 147cabdff1aSopenharmony_ci AV_PICTURE_TYPE_I; 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci if (ps->pps->output_flag_present_flag) 150cabdff1aSopenharmony_ci skip_bits1(gb); // pic_output_flag 151cabdff1aSopenharmony_ci 152cabdff1aSopenharmony_ci if (ps->sps->separate_colour_plane_flag) 153cabdff1aSopenharmony_ci skip_bits(gb, 2); // colour_plane_id 154cabdff1aSopenharmony_ci 155cabdff1aSopenharmony_ci if (!IS_IDR_NAL(nal)) { 156cabdff1aSopenharmony_ci int pic_order_cnt_lsb = get_bits(gb, ps->sps->log2_max_poc_lsb); 157cabdff1aSopenharmony_ci s->output_picture_number = ctx->poc = 158cabdff1aSopenharmony_ci ff_hevc_compute_poc(ps->sps, ctx->pocTid0, pic_order_cnt_lsb, nal->type); 159cabdff1aSopenharmony_ci } else 160cabdff1aSopenharmony_ci s->output_picture_number = ctx->poc = 0; 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci if (nal->temporal_id == 0 && 163cabdff1aSopenharmony_ci nal->type != HEVC_NAL_TRAIL_N && 164cabdff1aSopenharmony_ci nal->type != HEVC_NAL_TSA_N && 165cabdff1aSopenharmony_ci nal->type != HEVC_NAL_STSA_N && 166cabdff1aSopenharmony_ci nal->type != HEVC_NAL_RADL_N && 167cabdff1aSopenharmony_ci nal->type != HEVC_NAL_RASL_N && 168cabdff1aSopenharmony_ci nal->type != HEVC_NAL_RADL_R && 169cabdff1aSopenharmony_ci nal->type != HEVC_NAL_RASL_R) 170cabdff1aSopenharmony_ci ctx->pocTid0 = ctx->poc; 171cabdff1aSopenharmony_ci 172cabdff1aSopenharmony_ci return 1; /* no need to evaluate the rest */ 173cabdff1aSopenharmony_ci} 174cabdff1aSopenharmony_ci 175cabdff1aSopenharmony_ci/** 176cabdff1aSopenharmony_ci * Parse NAL units of found picture and decode some basic information. 177cabdff1aSopenharmony_ci * 178cabdff1aSopenharmony_ci * @param s parser context. 179cabdff1aSopenharmony_ci * @param avctx codec context. 180cabdff1aSopenharmony_ci * @param buf buffer with field/frame data. 181cabdff1aSopenharmony_ci * @param buf_size size of the buffer. 182cabdff1aSopenharmony_ci */ 183cabdff1aSopenharmony_cistatic int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf, 184cabdff1aSopenharmony_ci int buf_size, AVCodecContext *avctx) 185cabdff1aSopenharmony_ci{ 186cabdff1aSopenharmony_ci HEVCParserContext *ctx = s->priv_data; 187cabdff1aSopenharmony_ci HEVCParamSets *ps = &ctx->ps; 188cabdff1aSopenharmony_ci HEVCSEI *sei = &ctx->sei; 189cabdff1aSopenharmony_ci int ret, i; 190cabdff1aSopenharmony_ci 191cabdff1aSopenharmony_ci /* set some sane default values */ 192cabdff1aSopenharmony_ci s->pict_type = AV_PICTURE_TYPE_I; 193cabdff1aSopenharmony_ci s->key_frame = 0; 194cabdff1aSopenharmony_ci s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN; 195cabdff1aSopenharmony_ci 196cabdff1aSopenharmony_ci ff_hevc_reset_sei(sei); 197cabdff1aSopenharmony_ci 198cabdff1aSopenharmony_ci ret = ff_h2645_packet_split(&ctx->pkt, buf, buf_size, avctx, ctx->is_avc, 199cabdff1aSopenharmony_ci ctx->nal_length_size, AV_CODEC_ID_HEVC, 1, 0); 200cabdff1aSopenharmony_ci if (ret < 0) 201cabdff1aSopenharmony_ci return ret; 202cabdff1aSopenharmony_ci 203cabdff1aSopenharmony_ci for (i = 0; i < ctx->pkt.nb_nals; i++) { 204cabdff1aSopenharmony_ci H2645NAL *nal = &ctx->pkt.nals[i]; 205cabdff1aSopenharmony_ci GetBitContext *gb = &nal->gb; 206cabdff1aSopenharmony_ci 207cabdff1aSopenharmony_ci if (nal->nuh_layer_id > 0) 208cabdff1aSopenharmony_ci continue; 209cabdff1aSopenharmony_ci 210cabdff1aSopenharmony_ci switch (nal->type) { 211cabdff1aSopenharmony_ci case HEVC_NAL_VPS: 212cabdff1aSopenharmony_ci ff_hevc_decode_nal_vps(gb, avctx, ps); 213cabdff1aSopenharmony_ci break; 214cabdff1aSopenharmony_ci case HEVC_NAL_SPS: 215cabdff1aSopenharmony_ci ff_hevc_decode_nal_sps(gb, avctx, ps, 1); 216cabdff1aSopenharmony_ci break; 217cabdff1aSopenharmony_ci case HEVC_NAL_PPS: 218cabdff1aSopenharmony_ci ff_hevc_decode_nal_pps(gb, avctx, ps); 219cabdff1aSopenharmony_ci break; 220cabdff1aSopenharmony_ci case HEVC_NAL_SEI_PREFIX: 221cabdff1aSopenharmony_ci case HEVC_NAL_SEI_SUFFIX: 222cabdff1aSopenharmony_ci ff_hevc_decode_nal_sei(gb, avctx, sei, ps, nal->type); 223cabdff1aSopenharmony_ci break; 224cabdff1aSopenharmony_ci case HEVC_NAL_TRAIL_N: 225cabdff1aSopenharmony_ci case HEVC_NAL_TRAIL_R: 226cabdff1aSopenharmony_ci case HEVC_NAL_TSA_N: 227cabdff1aSopenharmony_ci case HEVC_NAL_TSA_R: 228cabdff1aSopenharmony_ci case HEVC_NAL_STSA_N: 229cabdff1aSopenharmony_ci case HEVC_NAL_STSA_R: 230cabdff1aSopenharmony_ci case HEVC_NAL_BLA_W_LP: 231cabdff1aSopenharmony_ci case HEVC_NAL_BLA_W_RADL: 232cabdff1aSopenharmony_ci case HEVC_NAL_BLA_N_LP: 233cabdff1aSopenharmony_ci case HEVC_NAL_IDR_W_RADL: 234cabdff1aSopenharmony_ci case HEVC_NAL_IDR_N_LP: 235cabdff1aSopenharmony_ci case HEVC_NAL_CRA_NUT: 236cabdff1aSopenharmony_ci case HEVC_NAL_RADL_N: 237cabdff1aSopenharmony_ci case HEVC_NAL_RADL_R: 238cabdff1aSopenharmony_ci case HEVC_NAL_RASL_N: 239cabdff1aSopenharmony_ci case HEVC_NAL_RASL_R: 240cabdff1aSopenharmony_ci if (ctx->sei.picture_timing.picture_struct == HEVC_SEI_PIC_STRUCT_FRAME_DOUBLING) { 241cabdff1aSopenharmony_ci s->repeat_pict = 1; 242cabdff1aSopenharmony_ci } else if (ctx->sei.picture_timing.picture_struct == HEVC_SEI_PIC_STRUCT_FRAME_TRIPLING) { 243cabdff1aSopenharmony_ci s->repeat_pict = 2; 244cabdff1aSopenharmony_ci } 245cabdff1aSopenharmony_ci ret = hevc_parse_slice_header(s, nal, avctx); 246cabdff1aSopenharmony_ci if (ret) 247cabdff1aSopenharmony_ci return ret; 248cabdff1aSopenharmony_ci break; 249cabdff1aSopenharmony_ci } 250cabdff1aSopenharmony_ci } 251cabdff1aSopenharmony_ci /* didn't find a picture! */ 252cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "missing picture in access unit with size %d\n", buf_size); 253cabdff1aSopenharmony_ci return -1; 254cabdff1aSopenharmony_ci} 255cabdff1aSopenharmony_ci 256cabdff1aSopenharmony_ci/** 257cabdff1aSopenharmony_ci * Find the end of the current frame in the bitstream. 258cabdff1aSopenharmony_ci * @return the position of the first byte of the next frame, or END_NOT_FOUND 259cabdff1aSopenharmony_ci */ 260cabdff1aSopenharmony_cistatic int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf, 261cabdff1aSopenharmony_ci int buf_size) 262cabdff1aSopenharmony_ci{ 263cabdff1aSopenharmony_ci HEVCParserContext *ctx = s->priv_data; 264cabdff1aSopenharmony_ci ParseContext *pc = &ctx->pc; 265cabdff1aSopenharmony_ci int i; 266cabdff1aSopenharmony_ci 267cabdff1aSopenharmony_ci for (i = 0; i < buf_size; i++) { 268cabdff1aSopenharmony_ci int nut; 269cabdff1aSopenharmony_ci 270cabdff1aSopenharmony_ci pc->state64 = (pc->state64 << 8) | buf[i]; 271cabdff1aSopenharmony_ci 272cabdff1aSopenharmony_ci if (((pc->state64 >> 3 * 8) & 0xFFFFFF) != START_CODE) 273cabdff1aSopenharmony_ci continue; 274cabdff1aSopenharmony_ci 275cabdff1aSopenharmony_ci nut = (pc->state64 >> 2 * 8 + 1) & 0x3F; 276cabdff1aSopenharmony_ci // Beginning of access unit 277cabdff1aSopenharmony_ci if ((nut >= HEVC_NAL_VPS && nut <= HEVC_NAL_EOB_NUT) || nut == HEVC_NAL_SEI_PREFIX || 278cabdff1aSopenharmony_ci (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) { 279cabdff1aSopenharmony_ci if (pc->frame_start_found) { 280cabdff1aSopenharmony_ci pc->frame_start_found = 0; 281cabdff1aSopenharmony_ci return i - 5; 282cabdff1aSopenharmony_ci } 283cabdff1aSopenharmony_ci } else if (nut <= HEVC_NAL_RASL_R || 284cabdff1aSopenharmony_ci (nut >= HEVC_NAL_BLA_W_LP && nut <= HEVC_NAL_CRA_NUT)) { 285cabdff1aSopenharmony_ci int first_slice_segment_in_pic_flag = buf[i] >> 7; 286cabdff1aSopenharmony_ci if (first_slice_segment_in_pic_flag) { 287cabdff1aSopenharmony_ci if (!pc->frame_start_found) { 288cabdff1aSopenharmony_ci pc->frame_start_found = 1; 289cabdff1aSopenharmony_ci } else { // First slice of next frame found 290cabdff1aSopenharmony_ci pc->frame_start_found = 0; 291cabdff1aSopenharmony_ci return i - 5; 292cabdff1aSopenharmony_ci } 293cabdff1aSopenharmony_ci } 294cabdff1aSopenharmony_ci } 295cabdff1aSopenharmony_ci } 296cabdff1aSopenharmony_ci 297cabdff1aSopenharmony_ci return END_NOT_FOUND; 298cabdff1aSopenharmony_ci} 299cabdff1aSopenharmony_ci 300cabdff1aSopenharmony_cistatic int hevc_parse(AVCodecParserContext *s, AVCodecContext *avctx, 301cabdff1aSopenharmony_ci const uint8_t **poutbuf, int *poutbuf_size, 302cabdff1aSopenharmony_ci const uint8_t *buf, int buf_size) 303cabdff1aSopenharmony_ci{ 304cabdff1aSopenharmony_ci int next; 305cabdff1aSopenharmony_ci HEVCParserContext *ctx = s->priv_data; 306cabdff1aSopenharmony_ci ParseContext *pc = &ctx->pc; 307cabdff1aSopenharmony_ci int is_dummy_buf = !buf_size; 308cabdff1aSopenharmony_ci const uint8_t *dummy_buf = buf; 309cabdff1aSopenharmony_ci 310cabdff1aSopenharmony_ci if (avctx->extradata && !ctx->parsed_extradata) { 311cabdff1aSopenharmony_ci ff_hevc_decode_extradata(avctx->extradata, avctx->extradata_size, &ctx->ps, &ctx->sei, 312cabdff1aSopenharmony_ci &ctx->is_avc, &ctx->nal_length_size, avctx->err_recognition, 313cabdff1aSopenharmony_ci 1, avctx); 314cabdff1aSopenharmony_ci ctx->parsed_extradata = 1; 315cabdff1aSopenharmony_ci } 316cabdff1aSopenharmony_ci 317cabdff1aSopenharmony_ci if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { 318cabdff1aSopenharmony_ci next = buf_size; 319cabdff1aSopenharmony_ci } else { 320cabdff1aSopenharmony_ci next = hevc_find_frame_end(s, buf, buf_size); 321cabdff1aSopenharmony_ci if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { 322cabdff1aSopenharmony_ci *poutbuf = NULL; 323cabdff1aSopenharmony_ci *poutbuf_size = 0; 324cabdff1aSopenharmony_ci return buf_size; 325cabdff1aSopenharmony_ci } 326cabdff1aSopenharmony_ci } 327cabdff1aSopenharmony_ci 328cabdff1aSopenharmony_ci is_dummy_buf &= (dummy_buf == buf); 329cabdff1aSopenharmony_ci 330cabdff1aSopenharmony_ci if (!is_dummy_buf) 331cabdff1aSopenharmony_ci parse_nal_units(s, buf, buf_size, avctx); 332cabdff1aSopenharmony_ci 333cabdff1aSopenharmony_ci *poutbuf = buf; 334cabdff1aSopenharmony_ci *poutbuf_size = buf_size; 335cabdff1aSopenharmony_ci return next; 336cabdff1aSopenharmony_ci} 337cabdff1aSopenharmony_ci 338cabdff1aSopenharmony_cistatic void hevc_parser_close(AVCodecParserContext *s) 339cabdff1aSopenharmony_ci{ 340cabdff1aSopenharmony_ci HEVCParserContext *ctx = s->priv_data; 341cabdff1aSopenharmony_ci 342cabdff1aSopenharmony_ci ff_hevc_ps_uninit(&ctx->ps); 343cabdff1aSopenharmony_ci ff_h2645_packet_uninit(&ctx->pkt); 344cabdff1aSopenharmony_ci ff_hevc_reset_sei(&ctx->sei); 345cabdff1aSopenharmony_ci 346cabdff1aSopenharmony_ci av_freep(&ctx->pc.buffer); 347cabdff1aSopenharmony_ci} 348cabdff1aSopenharmony_ci 349cabdff1aSopenharmony_ciconst AVCodecParser ff_hevc_parser = { 350cabdff1aSopenharmony_ci .codec_ids = { AV_CODEC_ID_HEVC }, 351cabdff1aSopenharmony_ci .priv_data_size = sizeof(HEVCParserContext), 352cabdff1aSopenharmony_ci .parser_parse = hevc_parse, 353cabdff1aSopenharmony_ci .parser_close = hevc_parser_close, 354cabdff1aSopenharmony_ci}; 355