LCOV - code coverage report
Current view: top level - libavcodec - hevc_parse.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 52 65 80.0 %
Date: 2017-12-16 21:16:39 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :  * This file is part of FFmpeg.
       3             :  *
       4             :  * FFmpeg is free software; you can redistribute it and/or
       5             :  * modify it under the terms of the GNU Lesser General Public
       6             :  * License as published by the Free Software Foundation; either
       7             :  * version 2.1 of the License, or (at your option) any later version.
       8             :  *
       9             :  * FFmpeg is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             :  * Lesser General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public
      15             :  * License along with FFmpeg; if not, write to the Free Software
      16             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      17             :  */
      18             : 
      19             : #include "bytestream.h"
      20             : #include "h2645_parse.h"
      21             : #include "hevc.h"
      22             : #include "hevc_parse.h"
      23             : 
      24         192 : static int hevc_decode_nal_units(const uint8_t *buf, int buf_size, HEVCParamSets *ps,
      25             :                                  HEVCSEI *sei, int is_nalff, int nal_length_size,
      26             :                                  int err_recognition, int apply_defdispwin, void *logctx)
      27             : {
      28             :     int i;
      29         192 :     int ret = 0;
      30         192 :     H2645Packet pkt = { 0 };
      31             : 
      32         192 :     ret = ff_h2645_packet_split(&pkt, buf, buf_size, logctx, is_nalff, nal_length_size, AV_CODEC_ID_HEVC, 1);
      33         192 :     if (ret < 0) {
      34           0 :         goto done;
      35             :     }
      36             : 
      37         791 :     for (i = 0; i < pkt.nb_nals; i++) {
      38         600 :         H2645NAL *nal = &pkt.nals[i];
      39             : 
      40             :         /* ignore everything except parameter sets and VCL NALUs */
      41         600 :         switch (nal->type) {
      42         179 :         case HEVC_NAL_VPS:
      43         179 :             ret = ff_hevc_decode_nal_vps(&nal->gb, logctx, ps);
      44         179 :             if (ret < 0)
      45           0 :                 goto done;
      46         179 :             break;
      47         177 :         case HEVC_NAL_SPS:
      48         177 :             ret = ff_hevc_decode_nal_sps(&nal->gb, logctx, ps, apply_defdispwin);
      49         177 :             if (ret < 0)
      50           0 :                 goto done;
      51         177 :             break;
      52         240 :         case HEVC_NAL_PPS:
      53         240 :             ret = ff_hevc_decode_nal_pps(&nal->gb, logctx, ps);
      54         240 :             if (ret < 0)
      55           1 :                 goto done;
      56         239 :             break;
      57           4 :         case HEVC_NAL_SEI_PREFIX:
      58             :         case HEVC_NAL_SEI_SUFFIX:
      59           4 :             ret = ff_hevc_decode_nal_sei(&nal->gb, logctx, sei, ps, nal->type);
      60           4 :             if (ret < 0)
      61           0 :                 goto done;
      62           4 :             break;
      63           0 :         default:
      64           0 :             av_log(logctx, AV_LOG_VERBOSE, "Ignoring NAL type %d in extradata\n", nal->type);
      65           0 :             break;
      66             :         }
      67             :     }
      68             : 
      69         191 : done:
      70         192 :     ff_h2645_packet_uninit(&pkt);
      71         192 :     if (err_recognition & AV_EF_EXPLODE)
      72           0 :         return ret;
      73             : 
      74         192 :     return 0;
      75             : }
      76             : 
      77         172 : int ff_hevc_decode_extradata(const uint8_t *data, int size, HEVCParamSets *ps,
      78             :                              HEVCSEI *sei, int *is_nalff, int *nal_length_size,
      79             :                              int err_recognition, int apply_defdispwin, void *logctx)
      80             : {
      81         172 :     int ret = 0;
      82             :     GetByteContext gb;
      83             : 
      84         172 :     bytestream2_init(&gb, data, size);
      85             : 
      86         180 :     if (size > 3 && (data[0] || data[1] || data[2] > 1)) {
      87             :         /* It seems the extradata is encoded as hvcC format.
      88             :          * Temporarily, we support configurationVersion==0 until 14496-15 3rd
      89             :          * is finalized. When finalized, configurationVersion will be 1 and we
      90             :          * can recognize hvcC by checking if avctx->extradata[0]==1 or not. */
      91             :         int i, j, num_arrays, nal_len_size;
      92             : 
      93           8 :         *is_nalff = 1;
      94             : 
      95           8 :         bytestream2_skip(&gb, 21);
      96           8 :         nal_len_size = (bytestream2_get_byte(&gb) & 3) + 1;
      97           8 :         num_arrays   = bytestream2_get_byte(&gb);
      98             : 
      99             :         /* nal units in the hvcC always have length coded with 2 bytes,
     100             :          * so put a fake nal_length_size = 2 while parsing them */
     101           8 :         *nal_length_size = 2;
     102             : 
     103             :         /* Decode nal units from hvcC. */
     104          36 :         for (i = 0; i < num_arrays; i++) {
     105          28 :             int type = bytestream2_get_byte(&gb) & 0x3f;
     106          28 :             int cnt  = bytestream2_get_be16(&gb);
     107             : 
     108          56 :             for (j = 0; j < cnt; j++) {
     109             :                 // +2 for the nal size field
     110          28 :                 int nalsize = bytestream2_peek_be16(&gb) + 2;
     111          28 :                 if (bytestream2_get_bytes_left(&gb) < nalsize) {
     112           0 :                     av_log(logctx, AV_LOG_ERROR,
     113             :                            "Invalid NAL unit size in extradata.\n");
     114           0 :                     return AVERROR_INVALIDDATA;
     115             :                 }
     116             : 
     117          28 :                 ret = hevc_decode_nal_units(gb.buffer, nalsize, ps, sei, *is_nalff,
     118             :                                             *nal_length_size, err_recognition, apply_defdispwin,
     119             :                                             logctx);
     120          28 :                 if (ret < 0) {
     121           0 :                     av_log(logctx, AV_LOG_ERROR,
     122             :                            "Decoding nal unit %d %d from hvcC failed\n",
     123             :                            type, i);
     124           0 :                     return ret;
     125             :                 }
     126          28 :                 bytestream2_skip(&gb, nalsize);
     127             :             }
     128             :         }
     129             : 
     130             :         /* Now store right nal length size, that will be used to parse
     131             :          * all other nals */
     132           8 :         *nal_length_size = nal_len_size;
     133             :     } else {
     134         164 :         *is_nalff = 0;
     135         164 :         ret = hevc_decode_nal_units(data, size, ps, sei, *is_nalff, *nal_length_size,
     136             :                                     err_recognition, apply_defdispwin, logctx);
     137         164 :         if (ret < 0)
     138           0 :             return ret;
     139             :     }
     140             : 
     141         172 :     return ret;
     142             : }

Generated by: LCOV version 1.13