2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <media_codec_bitstream.h>
20 #include <gst/base/gstbytereader.h>
21 #include <gst/base/gstbitreader.h>
23 void mc_init_bits(mc_bitstream_t *stream, unsigned char *data, int size)
26 stream->numBytes = size;
29 stream->dataBitPos = 0;
33 short mc_show_bits(mc_bitstream_t *stream, unsigned char nbits, unsigned int *pulOutData)
36 unsigned int dataBitPos = stream->dataBitPos;
37 unsigned int bitcnt = stream->bitcnt;
38 unsigned int dataBytePos;
41 if (nbits > (32 - bitcnt)) {
42 dataBytePos = dataBitPos >> 3;
43 bitcnt = dataBitPos & 7;
44 if (dataBytePos > stream->numBytes - 4) {
46 for (i = 0; i < stream->numBytes - dataBytePos; i++) {
47 stream->buffer |= stream->data[dataBytePos + i];
50 stream->buffer <<= 8 * (3 - i);
52 bits = &stream->data[dataBytePos];
53 stream->buffer = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
55 stream->bitcnt = bitcnt;
59 *pulOutData = (stream->buffer >> (32 - bitcnt)) & mask[(unsigned short)nbits];
64 short mc_read_bits(mc_bitstream_t *stream, unsigned char nbits, unsigned int *pulOutData)
67 unsigned int dataBitPos = stream->dataBitPos;
68 unsigned int bitcnt = stream->bitcnt;
69 unsigned int dataBytePos;
71 if ((dataBitPos + nbits) > (stream->numBytes << 3)) {
76 if (nbits > (32 - bitcnt)) {
77 dataBytePos = dataBitPos >> 3;
78 bitcnt = dataBitPos & 7;
79 bits = &stream->data[dataBytePos];
80 stream->buffer = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
84 stream->dataBitPos += nbits;
85 stream->bitcnt = (unsigned char)(bitcnt + nbits);
88 *pulOutData = (stream->buffer >> (32 - stream->bitcnt)) & mask[(unsigned short)nbits];
93 short mc_byte_align(mc_bitstream_t *stream)
96 unsigned int dataBitPos = stream->dataBitPos;
97 unsigned int bitcnt = stream->bitcnt;
98 unsigned int dataBytePos;
99 unsigned int leftBits;
101 leftBits = 8 - (dataBitPos & 0x7);
103 if ((dataBitPos + 8) > (unsigned int)(stream->numBytes << 3))
108 dataBytePos = dataBitPos >> 3;
109 dataBitPos += leftBits;
114 dataBytePos = dataBitPos >> 3;
115 bits = &stream->data[dataBytePos];
116 stream->buffer = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
120 stream->dataBitPos = dataBitPos;
121 stream->bitcnt = bitcnt;
125 unsigned int __mc_bytestream_to_nal(unsigned char *data, int size)
127 unsigned char val, zero_count;
128 unsigned char *pNal = data;
150 if ((zero_count >= 2) && (val == 1))
160 return (index - zero_count - 1);
163 int __mc_decode_sps(mc_bitstream_t *pstream, int *width, int *height)
165 int ret = MC_ERROR_NONE;
166 unsigned int tmp = 0;
170 mc_read_bits(pstream, 8, &tmp);
171 mc_read_bits(pstream, 1, &tmp);
172 mc_read_bits(pstream, 1, &tmp);
173 mc_read_bits(pstream, 1, &tmp);
174 mc_read_bits(pstream, 5, &tmp);
175 mc_read_bits(pstream, 8, &tmp);
179 if (profile_idc > 51)
180 ret = MC_INVALID_IN_BUF;
182 /*TODO parse width, height, etc...*/
187 int __mc_scan_for_h264_start_codes(const guint8 * data, guint size)
190 gst_byte_reader_init(&br, data, size);
192 /* NALU not empty, so we can at least expect 1 (even 2) bytes following sc */
193 return gst_byte_reader_masked_scan_uint32(&br, 0xffffff00, 0x00000100, 0, size);
196 int _mc_check_h264_bytestream(unsigned char *nal, int byte_length, bool port, bool *codec_config, bool *sync_flag, bool *slice)
198 int ret = 0; /* (ret <= 0)==>>error occured; (ret > 0)==>>codec data size */
199 int stacked_length = 0;
201 unsigned int syntax = 0;
202 unsigned int state = 0;
204 int nal_unit_type = 0;
205 int codec_length = 0;
207 mc_bitstream_t pstream;
209 nal_unit_type = nal[2] == 1 ? (nal[3] & 0x1F) : (nal[4] & 0x1F);
211 if (nal_unit_type == 0x7 || nal_unit_type == 0x8 || nal_unit_type == 0x9) {
214 nal_length = __mc_bytestream_to_nal(nal + stacked_length, byte_length - stacked_length);
216 mc_init_bits(&pstream, nal + stacked_length, byte_length - stacked_length);
217 mc_read_bits(&pstream, 32, &syntax);
218 mc_read_bits(&pstream, 8, &syntax);
220 switch (syntax & 0x1F) {
221 case NAL_SEQUENCE_PARAMETER_SET:
222 LOGD("nal_unit_type : SPS");
223 if ((ret = __mc_decode_sps(&pstream, NULL, NULL)) != MC_ERROR_NONE)
225 state |= MC_EXIST_SPS;
226 codec_length += nal_length;
228 case NAL_PICTURE_PARAMETER_SET:
229 LOGD("nal_unit_type : PPS");
230 state |= MC_EXIST_PPS;
231 codec_length += nal_length;
234 LOGD("nal_unit_type : IDR");
235 state |= MC_EXIST_IDR;
238 state |= MC_EXIST_SLICE;
239 LOGD("nal_unit_type : %x", syntax & 0x1F);
243 LOGD("stacked_length : %d, nal_length : %d, byte_length : %d", stacked_length, nal_length, byte_length);
245 stacked_length += nal_length;
248 LOGD("codec_data length : %d", codec_length);
250 if ((stacked_length >= byte_length) || count > 5)
253 } else if (nal_unit_type == 0x5) {
254 state |= MC_EXIST_IDR;
255 LOGD("nal_unit_type is IDR");
256 } else if (nal_unit_type == 0x01 || nal_unit_type == 0x02 || nal_unit_type == 0x03 || nal_unit_type == 0x04) {
257 state |= MC_EXIST_SLICE;
258 LOGD("nal_unit_type : %x", nal_unit_type);
263 LOGD("for debug state :%d, %d", state, MC_VALID_FIRST_SLICE);
266 if (!port && !CHECK_VALID_PACKET(state, MC_VALID_FIRST_SLICE))
267 return MC_INVALID_IN_BUF;
271 *codec_config = CHECK_VALID_PACKET(state, MC_VALID_HEADER) ? 1 : 0;
272 *sync_flag = CHECK_VALID_PACKET(state, MC_EXIST_IDR) ? 1 : 0;
273 *slice = CHECK_VALID_PACKET(state, MC_EXIST_SLICE) ? 1 : 0;
279 int _mc_check_valid_h263_frame(unsigned char *p, int size)
281 unsigned char *end = p + size - 3;
285 /* Found the start of the frame, now try to find the end */
286 if ((p[0] == 0x00) && (p[1] == 0x00) && ((p[2]&0xFC) == 0x80))
289 } while (count == 1 && p < end);
292 return MC_INVALID_IN_BUF; /* frame boundary violated */
294 return MC_ERROR_NONE;
297 bool _mc_is_voss(unsigned char *buf, int size, int *codec_size)
299 unsigned char *p = buf;
300 unsigned char *end = p + size - 3;
304 if (!((p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xB0)))
308 for (; p < end ; p++) {
309 if ((p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xB6)) {
319 bool _mc_is_ivop(unsigned char *p, int size, int pos)
321 if (size < (pos + 5))
326 if ((p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xB6)) {
327 /* VOP_CODING_TYPE (binary) Coding method
328 // 00 intra-coded (I)
329 // 01 predictive-coded (P)
330 // 10 bidirectionally-predictive-coded (B)
333 if ((p[4] & 0xC0) == 0x0) /*I-VOP */
339 bool _mc_is_vop(unsigned char *p, int size, int pos)
341 if (size < (pos + 4))
346 if ((p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xB6))
352 int _mc_check_mpeg4_out_bytestream(unsigned char *buf, int buf_length, bool* need_codec_data, bool *need_sync_flag)
354 int codec_data_size = 0;
355 g_return_val_if_fail(need_codec_data != NULL, MC_PARAM_ERROR);
356 g_return_val_if_fail(need_sync_flag != NULL, MC_PARAM_ERROR);
358 *need_codec_data = FALSE;
359 *need_sync_flag = FALSE;
361 if (_mc_is_voss(buf, buf_length, &codec_data_size))
362 *need_codec_data = TRUE;
363 if (_mc_is_ivop(buf, buf_length, codec_data_size))
364 *need_sync_flag = TRUE;
366 return codec_data_size;
369 bool _mc_check_h263_out_bytestream(unsigned char *p, int buf_length, bool* need_sync_flag)
371 g_return_val_if_fail(need_sync_flag != NULL, MC_PARAM_ERROR);
373 *need_sync_flag = FALSE;
375 /* PSC not present */
376 if ((p[0] != 0x00) || (p[1] != 0x00) || ((p[2]&0xFC) != 0x80))
379 /* PTYPE Field, Bit 9: Picture Coding Type, "0" INTRA (I-picture), "1" INTER (P-picture) */
381 *need_sync_flag = TRUE;
386 int _mc_get_h264_codecdata_size(guint8 *data, int size)
390 bool is_bytestream = FALSE;
392 if ((offset = __mc_scan_for_h264_start_codes(data, size)) == -1) {
393 /*Packetized Format*/
394 is_bytestream = FALSE;
396 /*Byte-Stream Format*/
397 is_bytestream = TRUE;
401 /*Byte-Stream Format*/
402 data_size = _mc_check_h264_bytestream(data, size, 0, NULL, NULL, NULL);
403 if (data_size <= 0) {
404 LOGE("No valid SPS/PPS ...");
405 return MC_INVALID_IN_BUF;
409 /*Packetized Format*/
410 int num_sps = 0, num_pps = 0;
413 unsigned int state = 0;
417 /* parse the avcC data */
418 if (size < 7) { /* when numSPS==0 and numPPS==0, length is 7 bytes */
419 LOGE("If contains codec_data, size should over 7 bytes ...");
420 return MC_INVALID_IN_BUF;
422 /* parse the version, this must be 1 */
424 LOGE("If contains codec_data, first byte must be 1 ...");
425 return MC_INVALID_IN_BUF;
428 num_sps = data[5] & 0x1f;
430 for (i = 0; i < num_sps; i++) {
431 gst_bit_reader_init(&br, data + offset, size - offset);
432 nalu_size = gst_bit_reader_get_bits_uint32_unchecked(&br, 2 * 8);
434 offset += nalu_size + 2;
435 state |= MC_EXIST_SPS;
438 num_pps = data[offset];
441 for (i = 0; i < num_pps; i++) {
442 gst_bit_reader_init(&br, data + offset, size - offset);
443 nalu_size = gst_bit_reader_get_bits_uint32_unchecked(&br, 2 * 8);
445 offset += nalu_size + 2;
446 state |= MC_EXIST_PPS;
449 if (CHECK_VALID_PACKET(state, MC_VALID_HEADER)) {
450 LOGD("Found valid SPS/PPS data...\n");
454 return MC_INVALID_IN_BUF;