diff options
author | cvs2svn <admin@example.com> | 2009-10-21 00:02:02 +0000 |
---|---|---|
committer | cvs2svn <admin@example.com> | 2009-10-21 00:02:02 +0000 |
commit | 97a97ca3358eb48de3eb7a222e487e800566569f (patch) | |
tree | 97c920d0225a1c9773a3bce2207f261d7d230123 /tools/h264.c | |
parent | a61961358c5a2ec92340b3f8e056bab55438f103 (diff) | |
download | xineliboutput-CVS.tar.gz xineliboutput-CVS.tar.bz2 |
This commit was manufactured by cvs2svn to create branch 'CVS'.CVS
Diffstat (limited to 'tools/h264.c')
-rw-r--r-- | tools/h264.c | 224 |
1 files changed, 0 insertions, 224 deletions
diff --git a/tools/h264.c b/tools/h264.c deleted file mode 100644 index a729a289..00000000 --- a/tools/h264.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * h264.c: H.264 bitstream decoding - * - * See the main source file 'xineliboutput.c' for copyright information and - * how to reach the author. - * - * $Id: h264.c,v 1.7 2009-03-31 11:33:05 phintuka Exp $ - * - */ - -#include <stdint.h> -#include <string.h> - -#ifndef LOG_MODULENAME -# define LOG_MODULENAME "[h264 ] " -# define SysLogLevel iSysLogLevel -# include "../logdefs.h" -#endif - -#define NOCACHE 1 -#include "bitstream.h" - -#include "mpeg.h" -#include "h264.h" - - -int h264_parse_sps(const uint8_t *buf, int len, h264_sps_data_t *sps) -{ - br_state br = BR_INIT(buf, len); - int profile_idc, pic_order_cnt_type; - int frame_mbs_only; - int i, j; - - profile_idc = br_get_u8(&br); - LOGDBG("H.264 SPS: profile_idc %d", profile_idc); - /* constraint_set0_flag = br_get_bit(br); */ - /* constraint_set1_flag = br_get_bit(br); */ - /* constraint_set2_flag = br_get_bit(br); */ - /* constraint_set3_flag = br_get_bit(br); */ - /* reserved = br_get_bits(br,4); */ - /* level_idc = br_get_u8(br); */ - br_skip_bits(&br, 16); - br_skip_ue_golomb(&br); /* seq_parameter_set_id */ - if (profile_idc >= 100) { - if (br_get_ue_golomb(&br) == 3) /* chroma_format_idc */ - br_skip_bit(&br); /* residual_colour_transform_flag */ - br_skip_ue_golomb(&br); /* bit_depth_luma - 8 */ - br_skip_ue_golomb(&br); /* bit_depth_chroma - 8 */ - br_skip_bit(&br); /* transform_bypass */ - if (br_get_bit(&br)) /* seq_scaling_matrix_present */ - for (i = 0; i < 8; i++) - if (br_get_bit(&br)) { /* seq_scaling_list_present */ - int last = 8, next = 8, size = (i<6) ? 16 : 64; - for (j = 0; j < size; j++) { - if (next) - next = (last + br_get_se_golomb(&br)) & 0xff; - last = next ?: last; - } - } - } - - br_skip_ue_golomb(&br); /* log2_max_frame_num - 4 */ - pic_order_cnt_type = br_get_ue_golomb(&br); - if (pic_order_cnt_type == 0) - br_skip_ue_golomb(&br); /* log2_max_poc_lsb - 4 */ - else if (pic_order_cnt_type == 1) { - br_skip_bit(&br); /* delta_pic_order_always_zero */ - br_skip_se_golomb(&br); /* offset_for_non_ref_pic */ - br_skip_se_golomb(&br); /* offset_for_top_to_bottom_field */ - j = br_get_ue_golomb(&br); /* num_ref_frames_in_pic_order_cnt_cycle */ - for (i = 0; i < j; i++) - br_skip_se_golomb(&br); /* offset_for_ref_frame[i] */ - } - br_skip_ue_golomb(&br); /* ref_frames */ - br_skip_bit(&br); /* gaps_in_frame_num_allowed */ - sps->width /* mbs */ = br_get_ue_golomb(&br) + 1; - sps->height /* mbs */ = br_get_ue_golomb(&br) + 1; - frame_mbs_only = br_get_bit(&br); - LOGDBG("H.264 SPS: pic_width: %u mbs", (unsigned) sps->width); - LOGDBG("H.264 SPS: pic_height: %u mbs", (unsigned) sps->height); - LOGDBG("H.264 SPS: frame only flag: %d", frame_mbs_only); - - sps->width *= 16; - sps->height *= 16 * (2-frame_mbs_only); - - if (!frame_mbs_only) - if (br_get_bit(&br)) /* mb_adaptive_frame_field_flag */ - LOGDBG("H.264 SPS: MBAFF"); - br_skip_bit(&br); /* direct_8x8_inference_flag */ - if (br_get_bit(&br)) { /* frame_cropping_flag */ - uint32_t crop_left = br_get_ue_golomb(&br); - uint32_t crop_right = br_get_ue_golomb(&br); - uint32_t crop_top = br_get_ue_golomb(&br); - uint32_t crop_bottom = br_get_ue_golomb(&br); - LOGDBG("H.264 SPS: cropping %d %d %d %d", - crop_left, crop_top, crop_right, crop_bottom); - - sps->width -= 2*(crop_left + crop_right); - if (frame_mbs_only) - sps->height -= 2*(crop_top + crop_bottom); - else - sps->height -= 4*(crop_top + crop_bottom); - } - - /* VUI parameters */ - sps->pixel_aspect.num = 0; - if (br_get_bit(&br)) { /* vui_parameters_present flag */ - if (br_get_bit(&br)) { /* aspect_ratio_info_present */ - uint32_t aspect_ratio_idc = br_get_u8(&br); - LOGDBG("H.264 SPS: aspect_ratio_idc %d", aspect_ratio_idc); - - if (aspect_ratio_idc == 255 /* Extended_SAR */) { - sps->pixel_aspect.num = br_get_u16(&br); /* sar_width */ - sps->pixel_aspect.den = br_get_u16(&br); /* sar_height */ - LOGDBG("H.264 SPS: -> sar %dx%d", sps->pixel_aspect.num, sps->pixel_aspect.den); - } else { - static const mpeg_rational_t aspect_ratios[] = - { /* page 213: */ - /* 0: unknown */ - {0, 1}, - /* 1...16: */ - { 1, 1}, {12, 11}, {10, 11}, {16, 11}, { 40, 33}, {24, 11}, {20, 11}, {32, 11}, - {80, 33}, {18, 11}, {15, 11}, {64, 33}, {160, 99}, { 4, 3}, { 3, 2}, { 2, 1} - }; - - if (aspect_ratio_idc < sizeof(aspect_ratios)/sizeof(aspect_ratios[0])) { - memcpy(&sps->pixel_aspect, &aspect_ratios[aspect_ratio_idc], sizeof(mpeg_rational_t)); - LOGDBG("H.264 SPS: -> aspect ratio %d / %d", sps->pixel_aspect.num, sps->pixel_aspect.den); - } else { - LOGMSG("H.264 SPS: aspect_ratio_idc out of range !"); - } - } - } - } - - LOGDBG("H.264 SPS: -> video size %dx%d, aspect %d:%d", - sps->width, sps->height, sps->pixel_aspect.num, sps->pixel_aspect.den); - - if(BR_EOF(&br)) { - LOGDBG("H.264 SPS: not enough data ?"); - return 0; - } - return 1; -} - -static int h264_nal_unescape(uint8_t *dst, const uint8_t *src, int len) -{ - int s = 0, d = 0; - while (s < len) { - if (!src[s] && !src[s+1]) { - /* hit 00 00 xx */ - dst[d] = dst[d+1] = 0; - s += 2; - d += 2; - if (src[s] == 3) { - s++; /* 00 00 03 xx --> 00 00 xx */ - /*LOGDBG("h264_nal_unescape: hit 00 00 03 %02x", src[s]);*/ - if (s >= len) - return d; - } /* else if (src[s] == 0 || src[s] == 1) { - LOGDBG("h264_nal_unescape: invalid NAL sequence 00 00 %02x %02x", src[s], src[s+1]); - return -1; - }*/ - } - dst[d++] = src[s++]; - } - return d; -} - -int h264_get_picture_type(const uint8_t *buf, int len) -{ - int i; - for (i = 0; i < len-5; i++) { - if (buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 && buf[i + 3] == NAL_AUD) { - uint8_t type = (buf[i + 4] >> 5); - switch (type) { - case 0: case 3: case 5: return I_FRAME; - case 1: case 4: case 6: return P_FRAME; - case 2: case 7: return B_FRAME; - default:; - } - } - } - return NO_PICTURE; -} - -int h264_get_video_size(const uint8_t *buf, int len, video_size_t *size) -{ - int i; - - /* H.264 detection, search for NAL AUD */ - if (!IS_NAL_AUD(buf)) - return 0; - - /* if I-frame, search for NAL SPS */ - if (h264_get_picture_type(buf, len) != I_FRAME) - return 0; - - /* scan video packet for sequence parameter set */ - for (i = 5; i < len-4; i++) - if (buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 && (buf[i + 3] & 0x1f) == NAL_SPS) { - - uint8_t nal_data[len]; - int nal_len; - - LOGDBG("H.264: Found NAL SPS at offset %d/%d", i, len); - - if (0 < (nal_len = h264_nal_unescape(nal_data, buf+i+4, len-i-4))) { - - h264_sps_data_t sps = {0}; - - if (h264_parse_sps(nal_data, nal_len, &sps)) { - size->width = sps.width; - size->height = sps.height; - memcpy(&size->pixel_aspect, &sps.pixel_aspect, sizeof(mpeg_rational_t)); - return 1; - } - LOGMSG("h264_get_video_size: not enough data ?"); - } - } - - return 0; -} - |