mirror of https://github.com/FFmpeg/FFmpeg.git
It will be useful in the QSV HEVC encoder.pull/140/head
parent
fd124d8357
commit
69ab9f53f9
4 changed files with 137 additions and 103 deletions
@ -0,0 +1,129 @@ |
||||
/*
|
||||
* HEVC common code |
||||
* |
||||
* This file is part of Libav. |
||||
* |
||||
* Libav is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* Libav is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with Libav; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#include <string.h> |
||||
|
||||
#include "config.h" |
||||
|
||||
#include "libavutil/intreadwrite.h" |
||||
#include "libavutil/mem.h" |
||||
|
||||
#include "hevc.h" |
||||
|
||||
/* FIXME: This is adapted from ff_h264_decode_nal, avoiding duplication
|
||||
* between these functions would be nice. */ |
||||
int ff_hevc_extract_rbsp(const uint8_t *src, int length, |
||||
HEVCNAL *nal) |
||||
{ |
||||
int i, si, di; |
||||
uint8_t *dst; |
||||
|
||||
#define STARTCODE_TEST \ |
||||
if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) { \
|
||||
if (src[i + 2] != 3) { \
|
||||
/* startcode, so we must be past the end */ \
|
||||
length = i; \
|
||||
} \
|
||||
break; \
|
||||
} |
||||
#if HAVE_FAST_UNALIGNED |
||||
#define FIND_FIRST_ZERO \ |
||||
if (i > 0 && !src[i]) \
|
||||
i--; \
|
||||
while (src[i]) \
|
||||
i++ |
||||
#if HAVE_FAST_64BIT |
||||
for (i = 0; i + 1 < length; i += 9) { |
||||
if (!((~AV_RN64A(src + i) & |
||||
(AV_RN64A(src + i) - 0x0100010001000101ULL)) & |
||||
0x8000800080008080ULL)) |
||||
continue; |
||||
FIND_FIRST_ZERO; |
||||
STARTCODE_TEST; |
||||
i -= 7; |
||||
} |
||||
#else |
||||
for (i = 0; i + 1 < length; i += 5) { |
||||
if (!((~AV_RN32A(src + i) & |
||||
(AV_RN32A(src + i) - 0x01000101U)) & |
||||
0x80008080U)) |
||||
continue; |
||||
FIND_FIRST_ZERO; |
||||
STARTCODE_TEST; |
||||
i -= 3; |
||||
} |
||||
#endif /* HAVE_FAST_64BIT */ |
||||
#else |
||||
for (i = 0; i + 1 < length; i += 2) { |
||||
if (src[i]) |
||||
continue; |
||||
if (i > 0 && src[i - 1] == 0) |
||||
i--; |
||||
STARTCODE_TEST; |
||||
} |
||||
#endif /* HAVE_FAST_UNALIGNED */ |
||||
|
||||
if (i >= length - 1) { // no escaped 0
|
||||
nal->data = |
||||
nal->raw_data = src; |
||||
nal->size = |
||||
nal->raw_size = length; |
||||
return length; |
||||
} |
||||
|
||||
av_fast_malloc(&nal->rbsp_buffer, &nal->rbsp_buffer_size, |
||||
length + FF_INPUT_BUFFER_PADDING_SIZE); |
||||
if (!nal->rbsp_buffer) |
||||
return AVERROR(ENOMEM); |
||||
|
||||
dst = nal->rbsp_buffer; |
||||
|
||||
memcpy(dst, src, i); |
||||
si = di = i; |
||||
while (si + 2 < length) { |
||||
// remove escapes (very rare 1:2^22)
|
||||
if (src[si + 2] > 3) { |
||||
dst[di++] = src[si++]; |
||||
dst[di++] = src[si++]; |
||||
} else if (src[si] == 0 && src[si + 1] == 0) { |
||||
if (src[si + 2] == 3) { // escape
|
||||
dst[di++] = 0; |
||||
dst[di++] = 0; |
||||
si += 3; |
||||
|
||||
continue; |
||||
} else // next start code
|
||||
goto nsc; |
||||
} |
||||
|
||||
dst[di++] = src[si++]; |
||||
} |
||||
while (si < length) |
||||
dst[di++] = src[si++]; |
||||
|
||||
nsc: |
||||
memset(dst + di, 0, FF_INPUT_BUFFER_PADDING_SIZE); |
||||
|
||||
nal->data = dst; |
||||
nal->size = di; |
||||
nal->raw_data = src; |
||||
nal->raw_size = si; |
||||
return si; |
||||
} |
Loading…
Reference in new issue