LCOV - code coverage report
Current view: top level - src/libavformat - avc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 52 119 43.7 %
Date: 2017-01-28 02:43:52 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /*
       2             :  * AVC helper functions for muxers
       3             :  * Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@smartjog.com>
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : #include "libavutil/intreadwrite.h"
      23             : #include "avformat.h"
      24             : #include "avio.h"
      25             : #include "avc.h"
      26             : 
      27         434 : static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, const uint8_t *end)
      28             : {
      29         434 :     const uint8_t *a = p + 4 - ((intptr_t)p & 3);
      30             : 
      31        1321 :     for (end -= 3; p < a && p < end; p++) {
      32         936 :         if (p[0] == 0 && p[1] == 0 && p[2] == 1)
      33          49 :             return p;
      34             :     }
      35             : 
      36       16487 :     for (end -= 3; p < end; p += 4) {
      37       16438 :         uint32_t x = *(const uint32_t*)p;
      38             : //      if ((x - 0x01000100) & (~x) & 0x80008000) // little endian
      39             : //      if ((x - 0x00010001) & (~x) & 0x00800080) // big endian
      40       16438 :         if ((x - 0x01010101) & (~x) & 0x80808080) { // generic
      41         676 :             if (p[1] == 0) {
      42         260 :                 if (p[0] == 0 && p[2] == 1)
      43          88 :                     return p;
      44         172 :                 if (p[2] == 0 && p[3] == 1)
      45          78 :                     return p+1;
      46             :             }
      47         510 :             if (p[3] == 0) {
      48         274 :                 if (p[2] == 0 && p[4] == 1)
      49          90 :                     return p+2;
      50         184 :                 if (p[4] == 0 && p[5] == 1)
      51          80 :                     return p+3;
      52             :             }
      53             :         }
      54             :     }
      55             : 
      56         120 :     for (end += 3; p < end; p++) {
      57          71 :         if (p[0] == 0 && p[1] == 0 && p[2] == 1)
      58           0 :             return p;
      59             :     }
      60             : 
      61          49 :     return end + 3;
      62             : }
      63             : 
      64         434 : const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end){
      65         434 :     const uint8_t *out= ff_avc_find_startcode_internal(p, end);
      66         434 :     if(p<out && out<end && !out[-1]) out--;
      67         434 :     return out;
      68             : }
      69             : 
      70          49 : int ff_avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size)
      71             : {
      72          49 :     const uint8_t *p = buf_in;
      73          49 :     const uint8_t *end = p + size;
      74             :     const uint8_t *nal_start, *nal_end;
      75             : 
      76          49 :     size = 0;
      77          49 :     nal_start = ff_avc_find_startcode(p, end);
      78             :     for (;;) {
      79         819 :         while (nal_start < end && !*(nal_start++));
      80         434 :         if (nal_start == end)
      81          49 :             break;
      82             : 
      83         385 :         nal_end = ff_avc_find_startcode(nal_start, end);
      84         385 :         avio_wb32(pb, nal_end - nal_start);
      85         385 :         avio_write(pb, nal_start, nal_end - nal_start);
      86         385 :         size += 4 + nal_end - nal_start;
      87         385 :         nal_start = nal_end;
      88             :     }
      89          49 :     return size;
      90             : }
      91             : 
      92           1 : int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
      93             : {
      94             :     AVIOContext *pb;
      95           1 :     int ret = avio_open_dyn_buf(&pb);
      96           1 :     if(ret < 0)
      97           0 :         return ret;
      98             : 
      99           1 :     ff_avc_parse_nal_units(pb, buf_in, *size);
     100             : 
     101           1 :     av_freep(buf);
     102           1 :     *size = avio_close_dyn_buf(pb, buf);
     103           1 :     return 0;
     104             : }
     105             : 
     106          45 : int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
     107             : {
     108          45 :     if (len > 6) {
     109             :         /* check for H.264 start code */
     110          90 :         if (AV_RB32(data) == 0x00000001 ||
     111          45 :             AV_RB24(data) == 0x000001) {
     112           0 :             uint8_t *buf=NULL, *end, *start;
     113           0 :             uint32_t sps_size=0, pps_size=0;
     114           0 :             uint8_t *sps=0, *pps=0;
     115             : 
     116           0 :             int ret = ff_avc_parse_nal_units_buf(data, &buf, &len);
     117           0 :             if (ret < 0)
     118           0 :                 return ret;
     119           0 :             start = buf;
     120           0 :             end = buf + len;
     121             : 
     122             :             /* look for sps and pps */
     123           0 :             while (end - buf > 4) {
     124             :                 uint32_t size;
     125             :                 uint8_t nal_type;
     126           0 :                 size = FFMIN(AV_RB32(buf), end - buf - 4);
     127           0 :                 buf += 4;
     128           0 :                 nal_type = buf[0] & 0x1f;
     129             : 
     130           0 :                 if (nal_type == 7) { /* SPS */
     131           0 :                     sps = buf;
     132           0 :                     sps_size = size;
     133           0 :                 } else if (nal_type == 8) { /* PPS */
     134           0 :                     pps = buf;
     135           0 :                     pps_size = size;
     136             :                 }
     137             : 
     138           0 :                 buf += size;
     139             :             }
     140             : 
     141           0 :             if (!sps || !pps || sps_size < 4 || sps_size > UINT16_MAX || pps_size > UINT16_MAX)
     142           0 :                 return AVERROR_INVALIDDATA;
     143             : 
     144           0 :             avio_w8(pb, 1); /* version */
     145           0 :             avio_w8(pb, sps[1]); /* profile */
     146           0 :             avio_w8(pb, sps[2]); /* profile compat */
     147           0 :             avio_w8(pb, sps[3]); /* level */
     148           0 :             avio_w8(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */
     149           0 :             avio_w8(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
     150             : 
     151           0 :             avio_wb16(pb, sps_size);
     152           0 :             avio_write(pb, sps, sps_size);
     153           0 :             avio_w8(pb, 1); /* number of pps */
     154           0 :             avio_wb16(pb, pps_size);
     155           0 :             avio_write(pb, pps, pps_size);
     156           0 :             av_free(start);
     157             :         } else {
     158          45 :             avio_write(pb, data, len);
     159             :         }
     160             :     }
     161          45 :     return 0;
     162             : }
     163             : 
     164           0 : int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size)
     165             : {
     166             :     uint16_t sps_size, pps_size;
     167             :     uint8_t *out;
     168             :     int out_size;
     169             : 
     170           0 :     *buf = NULL;
     171           0 :     if (*size >= 4 && (AV_RB32(in) == 0x00000001 || AV_RB24(in) == 0x000001))
     172           0 :         return 0;
     173           0 :     if (*size < 11 || in[0] != 1)
     174           0 :         return AVERROR_INVALIDDATA;
     175             : 
     176           0 :     sps_size = AV_RB16(&in[6]);
     177           0 :     if (11 + sps_size > *size)
     178           0 :         return AVERROR_INVALIDDATA;
     179           0 :     pps_size = AV_RB16(&in[9 + sps_size]);
     180           0 :     if (11 + sps_size + pps_size > *size)
     181           0 :         return AVERROR_INVALIDDATA;
     182           0 :     out_size = 8 + sps_size + pps_size;
     183           0 :     out = av_mallocz(out_size + AV_INPUT_BUFFER_PADDING_SIZE);
     184           0 :     if (!out)
     185           0 :         return AVERROR(ENOMEM);
     186           0 :     AV_WB32(&out[0], 0x00000001);
     187           0 :     memcpy(out + 4, &in[8], sps_size);
     188           0 :     AV_WB32(&out[4 + sps_size], 0x00000001);
     189           0 :     memcpy(out + 8 + sps_size, &in[11 + sps_size], pps_size);
     190           0 :     *buf = out;
     191           0 :     *size = out_size;
     192           0 :     return 0;
     193             : }
     194             : 
     195           0 : const uint8_t *ff_avc_mp4_find_startcode(const uint8_t *start,
     196             :                                          const uint8_t *end,
     197             :                                          int nal_length_size)
     198             : {
     199           0 :     unsigned int res = 0;
     200             : 
     201           0 :     if (end - start < nal_length_size)
     202           0 :         return NULL;
     203           0 :     while (nal_length_size--)
     204           0 :         res = (res << 8) | *start++;
     205             : 
     206           0 :     if (res > end - start)
     207           0 :         return NULL;
     208             : 
     209           0 :     return start + res;
     210             : }

Generated by: LCOV version 1.12