#include <stdio.h>
#include <dlog.h>
#include <media_codec_bitstream.h>
+#include <gst/base/gstbytereader.h>
+#include <gst/base/gstbitreader.h>
void mc_init_bits(mc_bitstream_t *stream, unsigned char *data, int size)
{
return ret;
}
+int __mc_scan_for_h264_start_codes(const guint8 * data, guint size)
+{
+ GstByteReader br;
+ gst_byte_reader_init(&br, data, size);
+
+ /* NALU not empty, so we can at least expect 1 (even 2) bytes following sc */
+ return gst_byte_reader_masked_scan_uint32(&br, 0xffffff00, 0x00000100, 0, size);
+}
+
int _mc_check_h264_bytestream(unsigned char *nal, int byte_length, bool port, bool *codec_config, bool *sync_flag, bool *slice)
{
- int ret = MC_ERROR_NONE;
+ int ret = 0; /* (ret <= 0)==>>error occured; (ret > 0)==>>codec data size */
int stacked_length = 0;
int nal_length = 0;
unsigned int syntax = 0;
unsigned int state = 0;
int count = 0;
int nal_unit_type = 0;
+ int codec_length = 0;
mc_bitstream_t pstream;
if ((ret = __mc_decode_sps(&pstream, NULL, NULL)) != MC_ERROR_NONE)
return ret;
state |= MC_EXIST_SPS;
+ codec_length += nal_length;
break;
case NAL_PICTURE_PARAMETER_SET:
LOGD("nal_unit_type : PPS");
state |= MC_EXIST_PPS;
+ codec_length += nal_length;
break;
case NAL_SLICE_IDR:
LOGD("nal_unit_type : IDR");
stacked_length += nal_length;
count++;
+ LOGD("codec_data length : %d", codec_length);
+
if ((stacked_length >= byte_length) || count > 5)
break;
}
*slice = CHECK_VALID_PACKET(state, MC_EXIST_SLICE) ? 1 : 0;
}
- return ret;
+ return codec_length;
}
int _mc_check_valid_h263_frame(unsigned char *p, int size)
return TRUE;
}
+int _mc_get_h264_codecdata_size(guint8 *data, int size)
+{
+ int offset = 0;
+ int data_size = 0;
+ bool is_bytestream = FALSE;
+
+ if ((offset = __mc_scan_for_h264_start_codes(data, size)) == -1) {
+ /*Packetized Format*/
+ is_bytestream = FALSE;
+ } else {
+ /*Byte-Stream Format*/
+ is_bytestream = TRUE;
+ }
+
+ if (is_bytestream) {
+ /*Byte-Stream Format*/
+ data_size = _mc_check_h264_bytestream(data, size, 0, NULL, NULL, NULL);
+ if (data_size <= 0) {
+ LOGE("No valid SPS/PPS ...");
+ return MC_INVALID_IN_BUF;
+ }
+ return data_size;
+ } else {
+ /*Packetized Format*/
+ int num_sps = 0, num_pps = 0;
+ int nalu_size = 0;
+ int i = 0;
+ unsigned int state = 0;
+ GstBitReader br;
+
+ offset = 0;
+ /* parse the avcC data */
+ if (size < 7) { /* when numSPS==0 and numPPS==0, length is 7 bytes */
+ LOGE("If contains codec_data, size should over 7 bytes ...");
+ return MC_INVALID_IN_BUF;
+ }
+ /* parse the version, this must be 1 */
+ if (data[0] != 1) {
+ LOGE("If contains codec_data, first byte must be 1 ...");
+ return MC_INVALID_IN_BUF;
+ }
+
+ num_sps = data[5] & 0x1f;
+ offset = 6;
+ for (i = 0; i < num_sps; i++) {
+ gst_bit_reader_init(&br, data + offset, size - offset);
+ nalu_size = gst_bit_reader_get_bits_uint32_unchecked(&br, 2 * 8);
+
+ offset += nalu_size + 2;
+ state |= MC_EXIST_SPS;
+ }
+
+ num_pps = data[offset];
+ offset++;
+
+ for (i = 0; i < num_pps; i++) {
+ gst_bit_reader_init(&br, data + offset, size - offset);
+ nalu_size = gst_bit_reader_get_bits_uint32_unchecked(&br, 2 * 8);
+
+ offset += nalu_size + 2;
+ state |= MC_EXIST_PPS;
+ }
+
+ if (CHECK_VALID_PACKET(state, MC_VALID_HEADER)) {
+ LOGD("Found valid SPS/PPS data...\n");
+ return offset;
+ }
+
+ return MC_INVALID_IN_BUF;
+ }
+
+}