Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

refactor BitstreamConverter

  • Loading branch information...
commit 6191e523c53ce671e9a20e63bf2ba72eab1ee337 1 parent 309e015
@davilla davilla authored
Showing with 635 additions and 498 deletions.
  1. +588 −459 xbmc/utils/BitstreamConverter.cpp
  2. +47 −39 xbmc/utils/BitstreamConverter.h
View
1,047 xbmc/utils/BitstreamConverter.cpp
@@ -24,71 +24,22 @@
#include "BitstreamConverter.h"
-void CBitstreamConverter::bits_reader_set(bits_reader_t *br, uint8_t *buf, int len)
-{
- br->buffer = br->start = buf;
- br->offbits = 0;
- br->length = len;
- br->oflow = 0;
-}
-
-uint32_t CBitstreamConverter::read_bits(bits_reader_t *br, int nbits)
-{
- int i, nbytes;
- uint32_t ret = 0;
- uint8_t *buf;
-
- buf = br->buffer;
- nbytes = (br->offbits + nbits)/8;
- if ( ((br->offbits + nbits) %8 ) > 0 )
- nbytes++;
- if ( (buf + nbytes) > (br->start + br->length) ) {
- br->oflow = 1;
- return 0;
- }
- for ( i=0; i<nbytes; i++ )
- ret += buf[i]<<((nbytes-i-1)*8);
- i = (4-nbytes)*8+br->offbits;
- ret = ((ret<<i)>>i)>>((nbytes*8)-nbits-br->offbits);
-
- br->offbits += nbits;
- br->buffer += br->offbits / 8;
- br->offbits %= 8;
-
- return ret;
-}
-
-void CBitstreamConverter::skip_bits(bits_reader_t *br, int nbits)
-{
- br->offbits += nbits;
- br->buffer += br->offbits / 8;
- br->offbits %= 8;
- if ( br->buffer > (br->start + br->length) ) {
- br->oflow = 1;
- }
-}
-
-uint32_t CBitstreamConverter::get_bits(bits_reader_t *br, int nbits)
-{
- int i, nbytes;
- uint32_t ret = 0;
- uint8_t *buf;
-
- buf = br->buffer;
- nbytes = (br->offbits + nbits)/8;
- if ( ((br->offbits + nbits) %8 ) > 0 )
- nbytes++;
- if ( (buf + nbytes) > (br->start + br->length) ) {
- br->oflow = 1;
- return 0;
- }
- for ( i=0; i<nbytes; i++ )
- ret += buf[i]<<((nbytes-i-1)*8);
- i = (4-nbytes)*8+br->offbits;
- ret = ((ret<<i)>>i)>>((nbytes*8)-nbits-br->offbits);
-
- return ret;
-}
+enum {
+ NAL_SLICE=1,
+ NAL_DPA,
+ NAL_DPB,
+ NAL_DPC,
+ NAL_IDR_SLICE,
+ NAL_SEI,
+ NAL_SPS,
+ NAL_PPS,
+ NAL_AUD,
+ NAL_END_SEQUENCE,
+ NAL_END_STREAM,
+ NAL_FILLER_DATA,
+ NAL_SPS_EXT,
+ NAL_AUXILIARY_SLICE=19
+};
////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
@@ -98,7 +49,7 @@ uint32_t CBitstreamConverter::get_bits(bits_reader_t *br, int nbits)
// gsth264parse.c:
// * License as published by the Free Software Foundation; either
// * version 2.1 of the License, or (at your option) any later version.
-void CBitstreamConverter::nal_bs_init(nal_bitstream *bs, const uint8_t *data, size_t size)
+static void nal_bs_init(nal_bitstream *bs, const uint8_t *data, size_t size)
{
bs->data = data;
bs->end = data + size;
@@ -108,7 +59,7 @@ void CBitstreamConverter::nal_bs_init(nal_bitstream *bs, const uint8_t *data, si
bs->cache = 0xffffffff;
}
-uint32_t CBitstreamConverter::nal_bs_read(nal_bitstream *bs, int n)
+static uint32_t nal_bs_read(nal_bitstream *bs, int n)
{
uint32_t res = 0;
int shift;
@@ -158,13 +109,13 @@ uint32_t CBitstreamConverter::nal_bs_read(nal_bitstream *bs, int n)
return res;
}
-bool CBitstreamConverter::nal_bs_eos(nal_bitstream *bs)
+static bool nal_bs_eos(nal_bitstream *bs)
{
return (bs->data >= bs->end) && (bs->head == 0);
}
// read unsigned Exp-Golomb code
-int CBitstreamConverter::nal_bs_read_ue(nal_bitstream *bs)
+static int nal_bs_read_ue(nal_bitstream *bs)
{
int i = 0;
@@ -174,367 +125,155 @@ int CBitstreamConverter::nal_bs_read_ue(nal_bitstream *bs)
return ((1 << i) - 1 + nal_bs_read(bs, i));
}
-bool CBitstreamConverter::mpeg2_sequence_header(const uint8_t *data, const uint32_t size, mpeg2_sequence *sequence)
+static const uint8_t* avc_find_startcode_internal(const uint8_t *p, const uint8_t *end)
{
- // parse nal's until a sequence_header_code is found
- // and return the width, height, aspect ratio and frame rate if changed.
- bool changed = false;
-
- if (!data)
- return changed;
+ const uint8_t *a = p + 4 - ((intptr_t)p & 3);
- const uint8_t *p = data;
- const uint8_t *end = p + size;
- const uint8_t *nal_start, *nal_end;
+ for (end -= 3; p < a && p < end; p++)
+ {
+ if (p[0] == 0 && p[1] == 0 && p[2] == 1)
+ return p;
+ }
- nal_start = avc_find_startcode(p, end);
- while (nal_start < end)
+ for (end -= 3; p < end; p += 4)
{
- while (!*(nal_start++));
- nal_end = avc_find_startcode(nal_start, end);
- if (*nal_start == 0xB3)
+ uint32_t x = *(const uint32_t*)p;
+ if ((x - 0x01010101) & (~x) & 0x80808080) // generic
{
- nal_bitstream bs;
- nal_bs_init(&bs, nal_start, end - nal_start);
-
- // sequence_header_code
- nal_bs_read(&bs, 8);
-
- // width
- // nal_start + 12 bits == horizontal_size_value
- uint32_t width = nal_bs_read(&bs, 12);
- if (width != sequence->width)
- {
- changed = true;
- sequence->width = width;
- }
- // height
- // nal_start + 24 bits == vertical_size_value
- uint32_t height = nal_bs_read(&bs, 12);
- if (height != sequence->height)
- {
- changed = true;
- sequence->height = height;
- }
-
- // aspect ratio
- // nal_start + 28 bits == aspect_ratio_information
- float ratio = sequence->ratio;
- uint32_t ratio_info = nal_bs_read(&bs, 4);
- switch(ratio_info)
- {
- case 0x01:
- ratio = 1.0;
- break;
- default:
- case 0x02:
- ratio = 4.0/3.0;
- break;
- case 0x03:
- ratio = 16.0/9.0;
- break;
- case 0x04:
- ratio = 2.21;
- break;
- }
- if (ratio_info != sequence->ratio_info)
- {
- changed = true;
- sequence->ratio = ratio;
- sequence->ratio_info = ratio_info;
- }
-
- // frame rate
- // nal_start + 32 bits == frame_rate_code
- float rate = sequence->rate;
- uint32_t rate_info = nal_bs_read(&bs, 4);
- switch(rate_info)
- {
- default:
- case 0x01:
- rate = 24000.0 / 1001.0;
- break;
- case 0x02:
- rate = 24000.0 / 1000.0;
- break;
- case 0x03:
- rate = 25000.0 / 1000.0;
- break;
- case 0x04:
- rate = 30000.0 / 1001.0;
- break;
- case 0x05:
- rate = 30000.0 / 1000.0;
- break;
- case 0x06:
- rate = 50000.0 / 1000.0;
- break;
- case 0x07:
- rate = 60000.0 / 1001.0;
- break;
- case 0x08:
- rate = 60000.0 / 1000.0;
- break;
- }
- if (rate_info != sequence->rate_info)
+ if (p[1] == 0)
{
- changed = true;
- sequence->rate = rate;
- sequence->rate_info = rate_info;
+ if (p[0] == 0 && p[2] == 1)
+ return p;
+ if (p[2] == 0 && p[3] == 1)
+ return p+1;
}
- /*
- if (changed)
+ if (p[3] == 0)
{
- CLog::Log(LOGDEBUG, "CBitstreamConverter::mpeg2_sequence_header: "
- "width(%d), height(%d), ratio(%f), rate(%f)", width, height, ratio, rate);
+ if (p[2] == 0 && p[4] == 1)
+ return p+2;
+ if (p[4] == 0 && p[5] == 1)
+ return p+3;
}
- */
}
- nal_start = nal_end;
}
- return changed;
+ for (end += 3; p < end; p++)
+ {
+ if (p[0] == 0 && p[1] == 0 && p[2] == 1)
+ return p;
+ }
+
+ return end + 3;
}
-void CBitstreamConverter::parseh264_sps(const uint8_t *sps, const uint32_t sps_size, bool *interlaced, int32_t *max_ref_frames)
+static const uint8_t* avc_find_startcode(const uint8_t *p, const uint8_t *end)
{
- nal_bitstream bs;
- sps_info_struct sps_info;
+ const uint8_t *out = avc_find_startcode_internal(p, end);
+ if (p<out && out<end && !out[-1])
+ out--;
+ return out;
+}
- nal_bs_init(&bs, sps, sps_size);
+////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////
+CBitstreamParser::CBitstreamParser()
+{
+}
- sps_info.profile_idc = nal_bs_read(&bs, 8);
- nal_bs_read(&bs, 1); // constraint_set0_flag
- nal_bs_read(&bs, 1); // constraint_set1_flag
- nal_bs_read(&bs, 1); // constraint_set2_flag
- nal_bs_read(&bs, 1); // constraint_set3_flag
- nal_bs_read(&bs, 4); // reserved
- sps_info.level_idc = nal_bs_read(&bs, 8);
- sps_info.sps_id = nal_bs_read_ue(&bs);
+CBitstreamParser::~CBitstreamParser()
+{
+ Close();
+}
- if (sps_info.profile_idc == 100 ||
- sps_info.profile_idc == 110 ||
- sps_info.profile_idc == 122 ||
- sps_info.profile_idc == 244 ||
- sps_info.profile_idc == 44 ||
- sps_info.profile_idc == 83 ||
- sps_info.profile_idc == 86)
- {
- sps_info.chroma_format_idc = nal_bs_read_ue(&bs);
- if (sps_info.chroma_format_idc == 3)
- sps_info.separate_colour_plane_flag = nal_bs_read(&bs, 1);
- sps_info.bit_depth_luma_minus8 = nal_bs_read_ue(&bs);
- sps_info.bit_depth_chroma_minus8 = nal_bs_read_ue(&bs);
- sps_info.qpprime_y_zero_transform_bypass_flag = nal_bs_read(&bs, 1);
+bool CBitstreamParser::Open()
+{
+ return true;
+}
- sps_info.seq_scaling_matrix_present_flag = nal_bs_read (&bs, 1);
- if (sps_info.seq_scaling_matrix_present_flag)
- {
- /* TODO: unfinished */
- }
- }
- sps_info.log2_max_frame_num_minus4 = nal_bs_read_ue(&bs);
- if (sps_info.log2_max_frame_num_minus4 > 12)
- { // must be between 0 and 12
- // don't early return here - the bits we are using (profile/level/interlaced/ref frames)
- // might still be valid - let the parser go on and pray.
- //return;
+void CBitstreamParser::Close()
+{
+}
+
+const uint8_t* CBitstreamParser::find_start_code(const uint8_t *p,
+ const uint8_t *end, uint32_t *state)
+{
+ assert(p <= end);
+ if (p >= end)
+ return end;
+
+ for (int i = 0; i < 3; i++) {
+ uint32_t tmp = *state << 8;
+ *state = tmp + *(p++);
+ if (tmp == 0x100 || p == end)
+ return p;
}
- sps_info.pic_order_cnt_type = nal_bs_read_ue(&bs);
- if (sps_info.pic_order_cnt_type == 0)
- {
- sps_info.log2_max_pic_order_cnt_lsb_minus4 = nal_bs_read_ue(&bs);
+
+ while (p < end) {
+ if (p[-1] > 1 ) p += 3;
+ else if (p[-2] ) p += 2;
+ else if (p[-3]|(p[-1]-1)) p++;
+ else {
+ p++;
+ break;
+ }
}
- else if (sps_info.pic_order_cnt_type == 1)
- { // TODO: unfinished
- /*
- delta_pic_order_always_zero_flag = gst_nal_bs_read (bs, 1);
- offset_for_non_ref_pic = gst_nal_bs_read_se (bs);
- offset_for_top_to_bottom_field = gst_nal_bs_read_se (bs);
-
- num_ref_frames_in_pic_order_cnt_cycle = gst_nal_bs_read_ue (bs);
- for ( i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ )
- offset_for_ref_frame[i] = gst_nal_bs_read_se (bs);
- */
- }
-
- sps_info.max_num_ref_frames = nal_bs_read_ue(&bs);
- sps_info.gaps_in_frame_num_value_allowed_flag = nal_bs_read(&bs, 1);
- sps_info.pic_width_in_mbs_minus1 = nal_bs_read_ue(&bs);
- sps_info.pic_height_in_map_units_minus1 = nal_bs_read_ue(&bs);
- sps_info.frame_mbs_only_flag = nal_bs_read(&bs, 1);
- if (!sps_info.frame_mbs_only_flag)
- sps_info.mb_adaptive_frame_field_flag = nal_bs_read(&bs, 1);
-
- sps_info.direct_8x8_inference_flag = nal_bs_read(&bs, 1);
-
- sps_info.frame_cropping_flag = nal_bs_read(&bs, 1);
- if (sps_info.frame_cropping_flag)
- {
- sps_info.frame_crop_left_offset = nal_bs_read_ue(&bs);
- sps_info.frame_crop_right_offset = nal_bs_read_ue(&bs);
- sps_info.frame_crop_top_offset = nal_bs_read_ue(&bs);
- sps_info.frame_crop_bottom_offset = nal_bs_read_ue(&bs);
- }
+ p = FFMIN(p, end) - 4;
+ *state = BS_RB32(p);
- *interlaced = !sps_info.frame_mbs_only_flag;
- *max_ref_frames = sps_info.max_num_ref_frames;
+ return p + 4;
}
-const uint8_t *CBitstreamConverter::avc_find_startcode_internal(const uint8_t *p, const uint8_t *end)
+bool CBitstreamParser::FindIdrSlice(const uint8_t *buf, int buf_size)
{
- const uint8_t *a = p + 4 - ((intptr_t)p & 3);
+ if (!buf)
+ return false;
- for (end -= 3; p < a && p < end; p++)
- {
- if (p[0] == 0 && p[1] == 0 && p[2] == 1)
- return p;
- }
+ bool rtn = false;
+ uint32_t state = -1;
+ const uint8_t *buf_end = buf + buf_size;
- for (end -= 3; p < end; p += 4)
+ for(;;)
{
- uint32_t x = *(const uint32_t*)p;
- if ((x - 0x01010101) & (~x) & 0x80808080) // generic
+ buf = find_start_code(buf, buf_end, &state);
+ if (buf >= buf_end)
{
- if (p[1] == 0)
- {
- if (p[0] == 0 && p[2] == 1)
- return p;
- if (p[2] == 0 && p[3] == 1)
- return p+1;
- }
- if (p[3] == 0)
- {
- if (p[2] == 0 && p[4] == 1)
- return p+2;
- if (p[4] == 0 && p[5] == 1)
- return p+3;
- }
- }
- }
-
- for (end += 3; p < end; p++)
- {
- if (p[0] == 0 && p[1] == 0 && p[2] == 1)
- return p;
- }
-
- return end + 3;
-}
-
-const uint8_t *CBitstreamConverter::avc_find_startcode(const uint8_t *p, const uint8_t *end)
-{
- const uint8_t *out= avc_find_startcode_internal(p, end);
- if (p<out && out<end && !out[-1])
- out--;
- return out;
-}
-
-const int CBitstreamConverter::avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size)
-{
- const uint8_t *p = buf_in;
- const uint8_t *end = p + size;
- const uint8_t *nal_start, *nal_end;
-
- size = 0;
- nal_start = avc_find_startcode(p, end);
-
- for (;;)
- {
- while (nal_start < end && !*(nal_start++));
- if (nal_start == end)
+ //CLog::Log(LOGDEBUG, "FindIdrSlice: buf(%p), buf_end(%p)", buf, buf_end);
break;
-
- nal_end = avc_find_startcode(nal_start, end);
- m_dllAvFormat->avio_wb32(pb, nal_end - nal_start);
- m_dllAvFormat->avio_write(pb, nal_start, nal_end - nal_start);
- size += 4 + nal_end - nal_start;
- nal_start = nal_end;
- }
- return size;
-}
-
-const int CBitstreamConverter::avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
-{
- AVIOContext *pb;
- int ret = m_dllAvFormat->avio_open_dyn_buf(&pb);
- if (ret < 0)
- return ret;
-
- avc_parse_nal_units(pb, buf_in, *size);
-
- m_dllAvUtil->av_freep(buf);
- *size = m_dllAvFormat->avio_close_dyn_buf(pb, buf);
- return 0;
-}
-
-const int CBitstreamConverter::isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
-{
- // extradata from bytestream h264, convert to avcC atom data for bitstream
- if (len > 6)
- {
- /* check for h264 start code */
- if (BS_RB32(data) == 0x00000001 || BS_RB24(data) == 0x000001)
- {
- uint8_t *buf=NULL, *end, *start;
- uint32_t sps_size=0, pps_size=0;
- uint8_t *sps=0, *pps=0;
-
- int ret = avc_parse_nal_units_buf(data, &buf, &len);
- if (ret < 0)
- return ret;
- start = buf;
- end = buf + len;
-
- /* look for sps and pps */
- while (end - buf > 4)
- {
- uint32_t size;
- uint8_t nal_type;
- size = FFMIN(BS_RB32(buf), end - buf - 4);
- buf += 4;
- nal_type = buf[0] & 0x1f;
- if (nal_type == 7) /* SPS */
- {
- sps = buf;
- sps_size = size;
- }
- else if (nal_type == 8) /* PPS */
- {
- pps = buf;
- pps_size = size;
- }
- buf += size;
- }
- if (!sps || !pps || sps_size < 4 || sps_size > UINT16_MAX || pps_size > UINT16_MAX)
- assert(0);
-
- m_dllAvFormat->avio_w8(pb, 1); /* version */
- m_dllAvFormat->avio_w8(pb, sps[1]); /* profile */
- m_dllAvFormat->avio_w8(pb, sps[2]); /* profile compat */
- m_dllAvFormat->avio_w8(pb, sps[3]); /* level */
- m_dllAvFormat->avio_w8(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */
- m_dllAvFormat->avio_w8(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
-
- m_dllAvFormat->avio_wb16(pb, sps_size);
- m_dllAvFormat->avio_write(pb, sps, sps_size);
- if (pps)
- {
- m_dllAvFormat->avio_w8(pb, 1); /* number of pps */
- m_dllAvFormat->avio_wb16(pb, pps_size);
- m_dllAvFormat->avio_write(pb, pps, pps_size);
- }
- m_dllAvUtil->av_free(start);
}
- else
+
+ --buf;
+ int src_length = buf_end - buf;
+ switch (state & 0x1f)
{
- m_dllAvFormat->avio_write(pb, data, len);
+ default:
+ CLog::Log(LOGDEBUG, "FindIdrSlice: found nal_type(%d)", state & 0x1f);
+ break;
+ case NAL_SLICE:
+ CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_SLICE");
+ break;
+ case NAL_IDR_SLICE:
+ CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_IDR_SLICE");
+ rtn = true;
+ break;
+ case NAL_SEI:
+ CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_SEI");
+ break;
+ case NAL_SPS:
+ CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_SPS");
+ break;
+ case NAL_PPS:
+ CLog::Log(LOGDEBUG, "FindIdrSlice: found NAL_PPS");
+ break;
}
+ buf += src_length;
}
- return 0;
+
+ return rtn;
}
+////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////
CBitstreamConverter::CBitstreamConverter()
{
m_convert_bitstream = false;
@@ -549,6 +288,7 @@ CBitstreamConverter::CBitstreamConverter()
m_dllAvUtil = NULL;
m_dllAvFormat = NULL;
m_convert_bytestream = false;
+ m_sps_pps_context.sps_pps_data = NULL;
}
CBitstreamConverter::~CBitstreamConverter()
@@ -556,43 +296,53 @@ CBitstreamConverter::~CBitstreamConverter()
Close();
}
-bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int in_extrasize, bool to_annexb)
+bool CBitstreamConverter::Open(enum CodecID codec, uint8_t *in_extradata, int in_extrasize, bool to_annexb)
{
- m_codec = codec;
m_to_annexb = to_annexb;
- switch(codec)
+ m_codec = codec;
+ switch(m_codec)
{
case AV_CODEC_ID_H264:
if (in_extrasize < 7 || in_extradata == NULL)
{
- CLog::Log(LOGERROR, "CBitstreamConverter::Open avcC data too small or missing\n");
+ CLog::Log(LOGERROR, "CBitstreamConverter::Open avcC data too small or missing");
return false;
}
// valid avcC data (bitstream) always starts with the value 1 (version)
- if (m_to_annexb)
+ if(m_to_annexb)
{
- if ( *(char*)in_extradata == 1 )
+ if ( in_extradata[0] == 1 )
{
- CLog::Log(LOGINFO, "CBitstreamConverter::Open bitstream to annexb init\n");
- m_convert_bitstream = BitstreamConvertInit(in_extradata, in_extrasize);
+ CLog::Log(LOGINFO, "CBitstreamConverter::Open bitstream to annexb init");
+ m_dllAvUtil = new DllAvUtil;
+ if (!m_dllAvUtil->Load())
+ return false;
+
+ m_extrasize = in_extrasize;
+ m_extradata = (uint8_t*)m_dllAvUtil->av_malloc(in_extrasize);
+ memcpy(m_extradata, in_extradata, in_extrasize);
+ m_convert_bitstream = BitstreamConvertInit(m_extradata, m_extrasize);
return true;
}
}
else
{
+ m_dllAvUtil = new DllAvUtil;
+ if (!m_dllAvUtil->Load())
+ return false;
+
// valid avcC atom data always starts with the value 1 (version)
- if ( *in_extradata != 1 )
+ if ( in_extradata[0] != 1 )
{
if ( (in_extradata[0] == 0 && in_extradata[1] == 0 && in_extradata[2] == 0 && in_extradata[3] == 1) ||
(in_extradata[0] == 0 && in_extradata[1] == 0 && in_extradata[2] == 1) )
{
- CLog::Log(LOGINFO, "CBitstreamConverter::Open annexb to bitstream init\n");
+ CLog::Log(LOGINFO, "CBitstreamConverter::Open annexb to bitstream init");
// video content is from x264 or from bytestream h264 (AnnexB format)
// NAL reformating to bitstream format needed
- m_dllAvUtil = new DllAvUtil;
m_dllAvFormat = new DllAvFormat;
- if (!m_dllAvUtil->Load() || !m_dllAvFormat->Load())
+ if (!m_dllAvFormat->Load())
return false;
AVIOContext *pb;
@@ -606,7 +356,7 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int
// extract the avcC atom data into extradata then write it into avcCData for VDADecoder
in_extrasize = m_dllAvFormat->avio_close_dyn_buf(pb, &in_extradata);
// make a copy of extradata contents
- m_extradata = (uint8_t *)malloc(in_extrasize);
+ m_extradata = (uint8_t *)m_dllAvUtil->av_malloc(in_extrasize);
memcpy(m_extradata, in_extradata, in_extrasize);
m_extrasize = in_extrasize;
// done with the converted extradata, we MUST free using av_free
@@ -623,31 +373,32 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int
{
if (in_extradata[4] == 0xFE)
{
- CLog::Log(LOGINFO, "CBitstreamConverter::Open annexb to bitstream init 3 byte to 4 byte nal\n");
+ CLog::Log(LOGINFO, "CBitstreamConverter::Open annexb to bitstream init 3 byte to 4 byte nal");
// video content is from so silly encoder that think 3 byte NAL sizes
// are valid, setup to convert 3 byte NAL sizes to 4 byte.
- m_dllAvUtil = new DllAvUtil;
m_dllAvFormat = new DllAvFormat;
- if (!m_dllAvUtil->Load() || !m_dllAvFormat->Load())
+ if (!m_dllAvFormat->Load())
return false;
in_extradata[4] = 0xFF;
m_convert_3byteTo4byteNALSize = true;
- m_extradata = (uint8_t *)malloc(in_extrasize);
+ m_extradata = (uint8_t *)m_dllAvUtil->av_malloc(in_extrasize);
memcpy(m_extradata, in_extradata, in_extrasize);
m_extrasize = in_extrasize;
return true;
}
}
// valid avcC atom
- m_extradata = (uint8_t*)malloc(in_extrasize);
+ m_extradata = (uint8_t*)m_dllAvUtil->av_malloc(in_extrasize);
memcpy(m_extradata, in_extradata, in_extrasize);
m_extrasize = in_extrasize;
return true;
}
+ return false;
break;
default:
+ return false;
break;
}
return false;
@@ -655,29 +406,22 @@ bool CBitstreamConverter::Open(enum AVCodecID codec, uint8_t *in_extradata, int
void CBitstreamConverter::Close(void)
{
- if (m_convert_bitstream)
- {
- if (m_sps_pps_context.sps_pps_data)
- free(m_sps_pps_context.sps_pps_data), m_sps_pps_context.sps_pps_data = NULL;
- if (m_convertBuffer)
- free(m_convertBuffer), m_convertBuffer = NULL;
- m_convertSize = 0;
- }
+ if (m_sps_pps_context.sps_pps_data)
+ m_dllAvUtil->av_free(m_sps_pps_context.sps_pps_data), m_sps_pps_context.sps_pps_data = NULL;
- if (m_convert_bytestream)
- {
- if (m_convertBuffer)
- m_dllAvUtil->av_free(m_convertBuffer), m_convertBuffer = NULL;
- m_convertSize = 0;
- }
+ if (m_convertBuffer)
+ m_dllAvUtil->av_free(m_convertBuffer), m_convertBuffer = NULL;
+ m_convertSize = 0;
if (m_extradata)
- free(m_extradata), m_extradata = NULL;
+ m_dllAvUtil->av_free(m_extradata), m_extradata = NULL;
m_extrasize = 0;
-
+
m_inputSize = 0;
m_inputBuffer = NULL;
+
m_convert_bitstream = false;
+ m_convert_bytestream = false;
m_convert_3byteTo4byteNALSize = false;
if (m_dllAvUtil)
@@ -690,9 +434,9 @@ bool CBitstreamConverter::Convert(uint8_t *pData, int iSize)
{
if (m_convertBuffer)
free(m_convertBuffer), m_convertBuffer = NULL;
+ m_inputSize = 0;
m_convertSize = 0;
m_inputBuffer = NULL;
- m_inputSize = 0;
if (pData)
{
@@ -701,7 +445,6 @@ bool CBitstreamConverter::Convert(uint8_t *pData, int iSize)
if (m_to_annexb)
{
int demuxer_bytes = iSize;
-
uint8_t *demuxer_content = pData;
if (m_convert_bitstream)
@@ -715,41 +458,56 @@ bool CBitstreamConverter::Convert(uint8_t *pData, int iSize)
{
m_convertSize = bytestream_size;
m_convertBuffer = bytestream_buff;
+ return true;
}
else
{
- m_inputBuffer = pData;
- m_inputSize = iSize;
- CLog::Log(LOGERROR, "CBitstreamConverter::Convert error converting.\n");
+ m_convertSize = 0;
+ m_convertBuffer = NULL;
+ CLog::Log(LOGERROR, "CBitstreamConverter::Convert: error converting.");
+ return false;
}
}
else
{
+ m_inputSize = iSize;
m_inputBuffer = pData;
- m_inputSize = iSize;
+ return true;
}
- return true;
}
else
{
+ m_inputSize = iSize;
m_inputBuffer = pData;
- m_inputSize = iSize;
- if (m_convertBuffer)
- m_dllAvUtil->av_free(m_convertBuffer), m_convertBuffer = NULL;
- m_convertSize = 0;
-
if (m_convert_bytestream)
{
+ if(m_convertBuffer)
+ {
+ m_dllAvUtil->av_free(m_convertBuffer);
+ m_convertBuffer = NULL;
+ }
+ m_convertSize = 0;
+
// convert demuxer packet from bytestream (AnnexB) to bitstream
AVIOContext *pb;
- if (m_dllAvFormat->avio_open_dyn_buf(&pb) < 0)
+
+ if(m_dllAvFormat->avio_open_dyn_buf(&pb) < 0)
+ {
return false;
+ }
m_convertSize = avc_parse_nal_units(pb, pData, iSize);
m_convertSize = m_dllAvFormat->avio_close_dyn_buf(pb, &m_convertBuffer);
}
else if (m_convert_3byteTo4byteNALSize)
{
+ if(m_convertBuffer)
+ {
+ m_dllAvUtil->av_free(m_convertBuffer);
+ m_convertBuffer = NULL;
+ }
+ m_convertSize = 0;
+
// convert demuxer packet from 3 byte NAL sizes to 4 byte
AVIOContext *pb;
if (m_dllAvFormat->avio_open_dyn_buf(&pb) < 0)
@@ -766,6 +524,7 @@ bool CBitstreamConverter::Convert(uint8_t *pData, int iSize)
m_dllAvFormat->avio_write(pb, nal_start, nal_size);
nal_start += nal_size;
}
+
m_convertSize = m_dllAvFormat->avio_close_dyn_buf(pb, &m_convertBuffer);
}
return true;
@@ -779,35 +538,33 @@ bool CBitstreamConverter::Convert(uint8_t *pData, int iSize)
uint8_t *CBitstreamConverter::GetConvertBuffer()
{
- if ((m_convert_bitstream || m_convert_bytestream || m_convert_3byteTo4byteNALSize)
- && m_convertBuffer != NULL)
+ if((m_convert_bitstream || m_convert_bytestream || m_convert_3byteTo4byteNALSize) && m_convertBuffer != NULL)
return m_convertBuffer;
-
- return m_inputBuffer;
+ else
+ return m_inputBuffer;
}
int CBitstreamConverter::GetConvertSize()
{
- if ((m_convert_bitstream || m_convert_bytestream || m_convert_3byteTo4byteNALSize)
- && m_convertBuffer != NULL)
+ if((m_convert_bitstream || m_convert_bytestream || m_convert_3byteTo4byteNALSize) && m_convertBuffer != NULL)
return m_convertSize;
-
- return m_inputSize;
+ else
+ return m_inputSize;
}
uint8_t *CBitstreamConverter::GetExtraData()
{
- if (m_convert_bitstream)
+ if(m_convert_bitstream)
return m_sps_pps_context.sps_pps_data;
-
- return m_extradata;
+ else
+ return m_extradata;
}
int CBitstreamConverter::GetExtraSize()
{
- if (m_convert_bitstream)
+ if(m_convert_bitstream)
return m_sps_pps_context.size;
-
- return m_extrasize;
+ else
+ return m_extrasize;
}
bool CBitstreamConverter::BitstreamConvertInit(void *in_extradata, int in_extrasize)
@@ -847,10 +604,10 @@ bool CBitstreamConverter::BitstreamConvertInit(void *in_extradata, int in_extras
total_size += unit_size + 4;
if ( (extradata + 2 + unit_size) > ((uint8_t*)in_extradata + in_extrasize) )
{
- free(out);
+ m_dllAvUtil->av_free(out);
return false;
}
- out = (uint8_t*)realloc(out, total_size);
+ out = (uint8_t*)m_dllAvUtil->av_realloc(out, total_size);
if (!out)
return false;
@@ -922,8 +679,7 @@ bool CBitstreamConverter::BitstreamConvert(uint8_t* pData, int iSize, uint8_t **
return true;
fail:
- free(*poutbuf);
- *poutbuf = NULL;
+ m_dllAvUtil->av_free(*poutbuf), *poutbuf = NULL;
*poutbuf_size = 0;
return false;
}
@@ -945,7 +701,7 @@ void CBitstreamConverter::BitstreamAllocAndCopy( uint8_t **poutbuf, int *poutbuf
uint8_t nal_header_size = offset ? 3 : 4;
*poutbuf_size += sps_pps_size + in_size + nal_header_size;
- *poutbuf = (uint8_t*)realloc(*poutbuf, *poutbuf_size);
+ *poutbuf = (uint8_t*)m_dllAvUtil->av_realloc(*poutbuf, *poutbuf_size);
if (sps_pps)
memcpy(*poutbuf + offset, sps_pps, sps_pps_size);
@@ -962,4 +718,377 @@ void CBitstreamConverter::BitstreamAllocAndCopy( uint8_t **poutbuf, int *poutbuf
}
}
+const int CBitstreamConverter::avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size)
+{
+ const uint8_t *p = buf_in;
+ const uint8_t *end = p + size;
+ const uint8_t *nal_start, *nal_end;
+
+ size = 0;
+ nal_start = avc_find_startcode(p, end);
+
+ for (;;) {
+ while (nal_start < end && !*(nal_start++));
+ if (nal_start == end)
+ break;
+
+ nal_end = avc_find_startcode(nal_start, end);
+ m_dllAvFormat->avio_wb32(pb, nal_end - nal_start);
+ m_dllAvFormat->avio_write(pb, nal_start, nal_end - nal_start);
+ size += 4 + nal_end - nal_start;
+ nal_start = nal_end;
+ }
+ return size;
+}
+
+const int CBitstreamConverter::avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
+{
+ AVIOContext *pb;
+ int ret = m_dllAvFormat->avio_open_dyn_buf(&pb);
+ if (ret < 0)
+ return ret;
+
+ avc_parse_nal_units(pb, buf_in, *size);
+ m_dllAvUtil->av_freep(buf);
+ *size = m_dllAvFormat->avio_close_dyn_buf(pb, buf);
+ return 0;
+}
+
+const int CBitstreamConverter::isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
+{
+ // extradata from bytestream h264, convert to avcC atom data for bitstream
+ if (len > 6)
+ {
+ /* check for h264 start code */
+ if (BS_RB32(data) == 0x00000001 || BS_RB24(data) == 0x000001)
+ {
+ uint8_t *buf=NULL, *end, *start;
+ uint32_t sps_size=0, pps_size=0;
+ uint8_t *sps=0, *pps=0;
+
+ int ret = avc_parse_nal_units_buf(data, &buf, &len);
+ if (ret < 0)
+ return ret;
+ start = buf;
+ end = buf + len;
+
+ /* look for sps and pps */
+ while (end - buf > 4)
+ {
+ uint32_t size;
+ uint8_t nal_type;
+ size = FFMIN(BS_RB32(buf), end - buf - 4);
+ buf += 4;
+ nal_type = buf[0] & 0x1f;
+ if (nal_type == 7) /* SPS */
+ {
+ sps = buf;
+ sps_size = size;
+ }
+ else if (nal_type == 8) /* PPS */
+ {
+ pps = buf;
+ pps_size = size;
+ }
+ buf += size;
+ }
+ if (!sps || !pps || sps_size < 4 || sps_size > UINT16_MAX || pps_size > UINT16_MAX)
+ assert(0);
+
+ m_dllAvFormat->avio_w8(pb, 1); /* version */
+ m_dllAvFormat->avio_w8(pb, sps[1]); /* profile */
+ m_dllAvFormat->avio_w8(pb, sps[2]); /* profile compat */
+ m_dllAvFormat->avio_w8(pb, sps[3]); /* level */
+ m_dllAvFormat->avio_w8(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */
+ m_dllAvFormat->avio_w8(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
+
+ m_dllAvFormat->avio_wb16(pb, sps_size);
+ m_dllAvFormat->avio_write(pb, sps, sps_size);
+ if (pps)
+ {
+ m_dllAvFormat->avio_w8(pb, 1); /* number of pps */
+ m_dllAvFormat->avio_wb16(pb, pps_size);
+ m_dllAvFormat->avio_write(pb, pps, pps_size);
+ }
+ m_dllAvUtil->av_free(start);
+ }
+ else
+ {
+ m_dllAvFormat->avio_write(pb, data, len);
+ }
+ }
+ return 0;
+}
+
+void CBitstreamConverter::bits_reader_set( bits_reader_t *br, uint8_t *buf, int len )
+{
+ br->buffer = br->start = buf;
+ br->offbits = 0;
+ br->length = len;
+ br->oflow = 0;
+}
+
+uint32_t CBitstreamConverter::read_bits( bits_reader_t *br, int nbits )
+{
+ int i, nbytes;
+ uint32_t ret = 0;
+ uint8_t *buf;
+
+ buf = br->buffer;
+ nbytes = (br->offbits + nbits)/8;
+ if ( ((br->offbits + nbits) %8 ) > 0 )
+ nbytes++;
+ if ( (buf + nbytes) > (br->start + br->length) ) {
+ br->oflow = 1;
+ return 0;
+ }
+ for ( i=0; i<nbytes; i++ )
+ ret += buf[i]<<((nbytes-i-1)*8);
+ i = (4-nbytes)*8+br->offbits;
+ ret = ((ret<<i)>>i)>>((nbytes*8)-nbits-br->offbits);
+
+ br->offbits += nbits;
+ br->buffer += br->offbits / 8;
+ br->offbits %= 8;
+
+ return ret;
+}
+
+void CBitstreamConverter::skip_bits( bits_reader_t *br, int nbits )
+{
+ br->offbits += nbits;
+ br->buffer += br->offbits / 8;
+ br->offbits %= 8;
+ if ( br->buffer > (br->start + br->length) ) {
+ br->oflow = 1;
+ }
+}
+
+uint32_t CBitstreamConverter::get_bits( bits_reader_t *br, int nbits )
+{
+ int i, nbytes;
+ uint32_t ret = 0;
+ uint8_t *buf;
+
+ buf = br->buffer;
+ nbytes = (br->offbits + nbits)/8;
+ if ( ((br->offbits + nbits) %8 ) > 0 )
+ nbytes++;
+ if ( (buf + nbytes) > (br->start + br->length) ) {
+ br->oflow = 1;
+ return 0;
+ }
+ for ( i=0; i<nbytes; i++ )
+ ret += buf[i]<<((nbytes-i-1)*8);
+ i = (4-nbytes)*8+br->offbits;
+ ret = ((ret<<i)>>i)>>((nbytes*8)-nbits-br->offbits);
+
+ return ret;
+}
+
+bool CBitstreamConverter::mpeg2_sequence_header(const uint8_t *data, const uint32_t size, mpeg2_sequence *sequence)
+{
+ // parse nal's until a sequence_header_code is found
+ // and return the width, height, aspect ratio and frame rate if changed.
+ bool changed = false;
+
+ if (!data)
+ return changed;
+
+ const uint8_t *p = data;
+ const uint8_t *end = p + size;
+ const uint8_t *nal_start, *nal_end;
+
+ nal_start = avc_find_startcode(p, end);
+ while (nal_start < end)
+ {
+ while (!*(nal_start++));
+ nal_end = avc_find_startcode(nal_start, end);
+ if (*nal_start == 0xB3)
+ {
+ nal_bitstream bs;
+ nal_bs_init(&bs, nal_start, end - nal_start);
+
+ // sequence_header_code
+ nal_bs_read(&bs, 8);
+
+ // width
+ // nal_start + 12 bits == horizontal_size_value
+ uint32_t width = nal_bs_read(&bs, 12);
+ if (width != sequence->width)
+ {
+ changed = true;
+ sequence->width = width;
+ }
+ // height
+ // nal_start + 24 bits == vertical_size_value
+ uint32_t height = nal_bs_read(&bs, 12);
+ if (height != sequence->height)
+ {
+ changed = true;
+ sequence->height = height;
+ }
+
+ // aspect ratio
+ // nal_start + 28 bits == aspect_ratio_information
+ float ratio = sequence->ratio;
+ uint32_t ratio_info = nal_bs_read(&bs, 4);
+ switch(ratio_info)
+ {
+ case 0x01:
+ ratio = 1.0;
+ break;
+ default:
+ case 0x02:
+ ratio = 4.0/3.0;
+ break;
+ case 0x03:
+ ratio = 16.0/9.0;
+ break;
+ case 0x04:
+ ratio = 2.21;
+ break;
+ }
+ if (ratio_info != sequence->ratio_info)
+ {
+ changed = true;
+ sequence->ratio = ratio;
+ sequence->ratio_info = ratio_info;
+ }
+
+ // frame rate
+ // nal_start + 32 bits == frame_rate_code
+ float rate = sequence->rate;
+ uint32_t rate_info = nal_bs_read(&bs, 4);
+ switch(rate_info)
+ {
+ default:
+ case 0x01:
+ rate = 24000.0 / 1001.0;
+ break;
+ case 0x02:
+ rate = 24000.0 / 1000.0;
+ break;
+ case 0x03:
+ rate = 25000.0 / 1000.0;
+ break;
+ case 0x04:
+ rate = 30000.0 / 1001.0;
+ break;
+ case 0x05:
+ rate = 30000.0 / 1000.0;
+ break;
+ case 0x06:
+ rate = 50000.0 / 1000.0;
+ break;
+ case 0x07:
+ rate = 60000.0 / 1001.0;
+ break;
+ case 0x08:
+ rate = 60000.0 / 1000.0;
+ break;
+ }
+ if (rate_info != sequence->rate_info)
+ {
+ changed = true;
+ sequence->rate = rate;
+ sequence->rate_info = rate_info;
+ }
+ /*
+ if (changed)
+ {
+ CLog::Log(LOGDEBUG, "CBitstreamConverter::mpeg2_sequence_header: "
+ "width(%d), height(%d), ratio(%f), rate(%f)", width, height, ratio, rate);
+ }
+ */
+ }
+ nal_start = nal_end;
+ }
+
+ return changed;
+}
+
+void CBitstreamConverter::parseh264_sps(const uint8_t *sps, const uint32_t sps_size, bool *interlaced, int32_t *max_ref_frames)
+{
+ nal_bitstream bs;
+ sps_info_struct sps_info;
+
+ nal_bs_init(&bs, sps, sps_size);
+
+ sps_info.profile_idc = nal_bs_read(&bs, 8);
+ nal_bs_read(&bs, 1); // constraint_set0_flag
+ nal_bs_read(&bs, 1); // constraint_set1_flag
+ nal_bs_read(&bs, 1); // constraint_set2_flag
+ nal_bs_read(&bs, 1); // constraint_set3_flag
+ nal_bs_read(&bs, 4); // reserved
+ sps_info.level_idc = nal_bs_read(&bs, 8);
+ sps_info.sps_id = nal_bs_read_ue(&bs);
+
+ if (sps_info.profile_idc == 100 ||
+ sps_info.profile_idc == 110 ||
+ sps_info.profile_idc == 122 ||
+ sps_info.profile_idc == 244 ||
+ sps_info.profile_idc == 44 ||
+ sps_info.profile_idc == 83 ||
+ sps_info.profile_idc == 86)
+ {
+ sps_info.chroma_format_idc = nal_bs_read_ue(&bs);
+ if (sps_info.chroma_format_idc == 3)
+ sps_info.separate_colour_plane_flag = nal_bs_read(&bs, 1);
+ sps_info.bit_depth_luma_minus8 = nal_bs_read_ue(&bs);
+ sps_info.bit_depth_chroma_minus8 = nal_bs_read_ue(&bs);
+ sps_info.qpprime_y_zero_transform_bypass_flag = nal_bs_read(&bs, 1);
+
+ sps_info.seq_scaling_matrix_present_flag = nal_bs_read (&bs, 1);
+ if (sps_info.seq_scaling_matrix_present_flag)
+ {
+ /* TODO: unfinished */
+ }
+ }
+ sps_info.log2_max_frame_num_minus4 = nal_bs_read_ue(&bs);
+ if (sps_info.log2_max_frame_num_minus4 > 12)
+ { // must be between 0 and 12
+ return;
+ }
+ sps_info.pic_order_cnt_type = nal_bs_read_ue(&bs);
+ if (sps_info.pic_order_cnt_type == 0)
+ {
+ sps_info.log2_max_pic_order_cnt_lsb_minus4 = nal_bs_read_ue(&bs);
+ }
+ else if (sps_info.pic_order_cnt_type == 1)
+ { // TODO: unfinished
+ /*
+ delta_pic_order_always_zero_flag = gst_nal_bs_read (bs, 1);
+ offset_for_non_ref_pic = gst_nal_bs_read_se (bs);
+ offset_for_top_to_bottom_field = gst_nal_bs_read_se (bs);
+
+ num_ref_frames_in_pic_order_cnt_cycle = gst_nal_bs_read_ue (bs);
+ for( i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ )
+ offset_for_ref_frame[i] = gst_nal_bs_read_se (bs);
+ */
+ }
+
+ sps_info.max_num_ref_frames = nal_bs_read_ue(&bs);
+ sps_info.gaps_in_frame_num_value_allowed_flag = nal_bs_read(&bs, 1);
+ sps_info.pic_width_in_mbs_minus1 = nal_bs_read_ue(&bs);
+ sps_info.pic_height_in_map_units_minus1 = nal_bs_read_ue(&bs);
+
+ sps_info.frame_mbs_only_flag = nal_bs_read(&bs, 1);
+ if (!sps_info.frame_mbs_only_flag)
+ sps_info.mb_adaptive_frame_field_flag = nal_bs_read(&bs, 1);
+
+ sps_info.direct_8x8_inference_flag = nal_bs_read(&bs, 1);
+
+ sps_info.frame_cropping_flag = nal_bs_read(&bs, 1);
+ if (sps_info.frame_cropping_flag)
+ {
+ sps_info.frame_crop_left_offset = nal_bs_read_ue(&bs);
+ sps_info.frame_crop_right_offset = nal_bs_read_ue(&bs);
+ sps_info.frame_crop_top_offset = nal_bs_read_ue(&bs);
+ sps_info.frame_crop_bottom_offset = nal_bs_read_ue(&bs);
+ }
+
+ *interlaced = !sps_info.frame_mbs_only_flag;
+ *max_ref_frames = sps_info.max_num_ref_frames;
+}
View
86 xbmc/utils/BitstreamConverter.h
@@ -21,11 +21,11 @@
#ifndef _BITSTREAMCONVERTER_H_
#define _BITSTREAMCONVERTER_H_
-#include <stdio.h>
#include <stdint.h>
-
#include "DllAvUtil.h"
#include "DllAvFormat.h"
+#include "DllAvFilter.h"
+#include "DllAvCodec.h"
typedef struct {
uint8_t *buffer, *start;
@@ -113,44 +113,52 @@ typedef struct
int frame_crop_bottom_offset;
} sps_info_struct;
+class CBitstreamParser
+{
+public:
+ CBitstreamParser();
+ ~CBitstreamParser();
+
+ bool Open();
+ void Close();
+ bool FindIdrSlice(const uint8_t *buf, int buf_size);
+
+protected:
+ const uint8_t* find_start_code(const uint8_t *p, const uint8_t *end, uint32_t *state);
+};
+
class CBitstreamConverter
{
public:
CBitstreamConverter();
~CBitstreamConverter();
- // Required overrides
- static void bits_reader_set( bits_reader_t *br, uint8_t *buf, int len );
- static uint32_t read_bits( bits_reader_t *br, int nbits );
- static void skip_bits( bits_reader_t *br, int nbits );
- static uint32_t get_bits( bits_reader_t *br, int nbits );
-
- bool Open(enum AVCodecID codec, uint8_t *in_extradata, int in_extrasize, bool to_annexb);
- void Close(void);
- bool NeedConvert(void) { return m_convert_bitstream; };
- bool Convert(uint8_t *pData, int iSize);
- uint8_t *GetConvertBuffer(void);
- int GetConvertSize();
- uint8_t *GetExtraData(void);
- int GetExtraSize();
-
- static void parseh264_sps(const uint8_t *sps, const uint32_t sps_size, bool *interlaced, int32_t *max_ref_frames);
- static bool mpeg2_sequence_header(const uint8_t *data, const uint32_t size, mpeg2_sequence *sequence);
+
+ bool Open(enum CodecID codec, uint8_t *in_extradata, int in_extrasize, bool to_annexb);
+ void Close(void);
+ bool NeedConvert(void) { return m_convert_bitstream; };
+ bool Convert(uint8_t *pData, int iSize);
+ uint8_t* GetConvertBuffer(void);
+ int GetConvertSize();
+ uint8_t* GetExtraData(void);
+ int GetExtraSize();
+
+ static void bits_reader_set( bits_reader_t *br, uint8_t *buf, int len );
+ static uint32_t read_bits( bits_reader_t *br, int nbits );
+ static void skip_bits( bits_reader_t *br, int nbits );
+ static uint32_t get_bits( bits_reader_t *br, int nbits );
+
+ static void parseh264_sps(const uint8_t *sps, const uint32_t sps_size, bool *interlaced, int32_t *max_ref_frames);
+ static bool mpeg2_sequence_header(const uint8_t *data, const uint32_t size, mpeg2_sequence *sequence);
+
protected:
- // bytestream (Annex B) to bistream conversion support.
- static void nal_bs_init(nal_bitstream *bs, const uint8_t *data, size_t size);
- static uint32_t nal_bs_read(nal_bitstream *bs, int n);
- static bool nal_bs_eos(nal_bitstream *bs);
- static int nal_bs_read_ue(nal_bitstream *bs);
- static const uint8_t *avc_find_startcode_internal(const uint8_t *p, const uint8_t *end);
- static const uint8_t *avc_find_startcode(const uint8_t *p, const uint8_t *end);
- const int avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size);
- const int avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size);
- const int isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len);
+ const int avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size);
+ const int avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size);
+ const int isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len);
// bitstream to bytestream (Annex B) conversion support.
- bool BitstreamConvertInit(void *in_extradata, int in_extrasize);
- bool BitstreamConvert(uint8_t* pData, int iSize, uint8_t **poutbuf, int *poutbuf_size);
- void BitstreamAllocAndCopy( uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *sps_pps, uint32_t sps_pps_size, const uint8_t *in, uint32_t in_size);
+ bool BitstreamConvertInit(void *in_extradata, int in_extrasize);
+ bool BitstreamConvert(uint8_t* pData, int iSize, uint8_t **poutbuf, int *poutbuf_size);
+ void BitstreamAllocAndCopy(uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *sps_pps, uint32_t sps_pps_size, const uint8_t *in, uint32_t in_size);
typedef struct omx_bitstream_ctx {
uint8_t length_size;
@@ -159,9 +167,9 @@ class CBitstreamConverter
uint32_t size;
} omx_bitstream_ctx;
- uint8_t *m_convertBuffer;
+ uint8_t *m_convertBuffer;
int m_convertSize;
- uint8_t *m_inputBuffer;
+ uint8_t *m_inputBuffer;
int m_inputSize;
uint32_t m_sps_pps_size;
@@ -169,13 +177,13 @@ class CBitstreamConverter
bool m_convert_bitstream;
bool m_to_annexb;
- uint8_t *m_extradata;
+ uint8_t *m_extradata;
int m_extrasize;
bool m_convert_3byteTo4byteNALSize;
bool m_convert_bytestream;
- DllAvUtil *m_dllAvUtil;
- DllAvFormat *m_dllAvFormat;
- AVCodecID m_codec;
+ DllAvUtil *m_dllAvUtil;
+ DllAvFormat *m_dllAvFormat;
+ AVCodecID m_codec;
};
#endif
Please sign in to comment.
Something went wrong with that request. Please try again.