• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavformat/avc.c

Go to the documentation of this file.
00001 /*
00002  * AVC helper functions for muxers
00003  * Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@smartjog.com>
00004  *
00005  * This file is part of Libav.
00006  *
00007  * Libav is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * Libav is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with Libav; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00022 #include "libavutil/intreadwrite.h"
00023 #include "avformat.h"
00024 #include "avio.h"
00025 #include "avc.h"
00026 
00027 static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, const uint8_t *end)
00028 {
00029     const uint8_t *a = p + 4 - ((intptr_t)p & 3);
00030 
00031     for (end -= 3; p < a && p < end; p++) {
00032         if (p[0] == 0 && p[1] == 0 && p[2] == 1)
00033             return p;
00034     }
00035 
00036     for (end -= 3; p < end; p += 4) {
00037         uint32_t x = *(const uint32_t*)p;
00038 //      if ((x - 0x01000100) & (~x) & 0x80008000) // little endian
00039 //      if ((x - 0x00010001) & (~x) & 0x00800080) // big endian
00040         if ((x - 0x01010101) & (~x) & 0x80808080) { // generic
00041             if (p[1] == 0) {
00042                 if (p[0] == 0 && p[2] == 1)
00043                     return p;
00044                 if (p[2] == 0 && p[3] == 1)
00045                     return p+1;
00046             }
00047             if (p[3] == 0) {
00048                 if (p[2] == 0 && p[4] == 1)
00049                     return p+2;
00050                 if (p[4] == 0 && p[5] == 1)
00051                     return p+3;
00052             }
00053         }
00054     }
00055 
00056     for (end += 3; p < end; p++) {
00057         if (p[0] == 0 && p[1] == 0 && p[2] == 1)
00058             return p;
00059     }
00060 
00061     return end + 3;
00062 }
00063 
00064 const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end){
00065     const uint8_t *out= ff_avc_find_startcode_internal(p, end);
00066     if(p<out && out<end && !out[-1]) out--;
00067     return out;
00068 }
00069 
00070 int ff_avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size)
00071 {
00072     const uint8_t *p = buf_in;
00073     const uint8_t *end = p + size;
00074     const uint8_t *nal_start, *nal_end;
00075 
00076     size = 0;
00077     nal_start = ff_avc_find_startcode(p, end);
00078     for (;;) {
00079         while (nal_start < end && !*(nal_start++));
00080         if (nal_start == end)
00081             break;
00082 
00083         nal_end = ff_avc_find_startcode(nal_start, end);
00084         avio_wb32(pb, nal_end - nal_start);
00085         avio_write(pb, nal_start, nal_end - nal_start);
00086         size += 4 + nal_end - nal_start;
00087         nal_start = nal_end;
00088     }
00089     return size;
00090 }
00091 
00092 int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
00093 {
00094     AVIOContext *pb;
00095     int ret = avio_open_dyn_buf(&pb);
00096     if(ret < 0)
00097         return ret;
00098 
00099     ff_avc_parse_nal_units(pb, buf_in, *size);
00100 
00101     av_freep(buf);
00102     *size = avio_close_dyn_buf(pb, buf);
00103     return 0;
00104 }
00105 
00106 int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
00107 {
00108     if (len > 6) {
00109         /* check for h264 start code */
00110         if (AV_RB32(data) == 0x00000001 ||
00111             AV_RB24(data) == 0x000001) {
00112             uint8_t *buf=NULL, *end, *start;
00113             uint32_t sps_size=0, pps_size=0;
00114             uint8_t *sps=0, *pps=0;
00115 
00116             int ret = ff_avc_parse_nal_units_buf(data, &buf, &len);
00117             if (ret < 0)
00118                 return ret;
00119             start = buf;
00120             end = buf + len;
00121 
00122             /* look for sps and pps */
00123             while (end - buf > 4) {
00124                 uint32_t size;
00125                 uint8_t nal_type;
00126                 size = FFMIN(AV_RB32(buf), end - buf - 4);
00127                 buf += 4;
00128                 nal_type = buf[0] & 0x1f;
00129 
00130                 if (nal_type == 7) { /* SPS */
00131                     sps = buf;
00132                     sps_size = size;
00133                 } else if (nal_type == 8) { /* PPS */
00134                     pps = buf;
00135                     pps_size = size;
00136                 }
00137 
00138                 buf += size;
00139             }
00140 
00141             if (!sps || !pps || sps_size < 4 || sps_size > UINT16_MAX || pps_size > UINT16_MAX)
00142                 return AVERROR_INVALIDDATA;
00143 
00144             avio_w8(pb, 1); /* version */
00145             avio_w8(pb, sps[1]); /* profile */
00146             avio_w8(pb, sps[2]); /* profile compat */
00147             avio_w8(pb, sps[3]); /* level */
00148             avio_w8(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */
00149             avio_w8(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
00150 
00151             avio_wb16(pb, sps_size);
00152             avio_write(pb, sps, sps_size);
00153             avio_w8(pb, 1); /* number of pps */
00154             avio_wb16(pb, pps_size);
00155             avio_write(pb, pps, pps_size);
00156             av_free(start);
00157         } else {
00158             avio_write(pb, data, len);
00159         }
00160     }
00161     return 0;
00162 }
Generated on Sat Mar 17 2012 12:57:53 for Libav by doxygen 1.7.1