Initial setup for CLion
This commit is contained in:
259
MediaClient/media/media_parse.cpp
Normal file
259
MediaClient/media/media_parse.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
*
|
||||
* By downloading, copying, installing or using the software you agree to this license.
|
||||
* If you do not agree to this license, do not download, install,
|
||||
* copy or use the software.
|
||||
*
|
||||
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
|
||||
*
|
||||
* Redistribution and use in binary forms, with or without modification, are permitted.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed
|
||||
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the License.
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#include "media_parse.h"
|
||||
#include "media_format.h"
|
||||
#include "media_util.h"
|
||||
#include "h264.h"
|
||||
#include "h265.h"
|
||||
#include "mjpeg.h"
|
||||
#include "h264_util.h"
|
||||
#include "h265_util.h"
|
||||
#include "bs.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
int avc_parse_video_size(int codec, uint8 * p_data, uint32 len, int * width, int * height)
|
||||
{
|
||||
uint8 nalu_t;
|
||||
|
||||
if (p_data == NULL || len < 5)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Need to parse width X height
|
||||
|
||||
if (VIDEO_CODEC_H264 == codec)
|
||||
{
|
||||
int s_len = 0, n_len = 0, parse_len = len;
|
||||
uint8 * p_cur = p_data;
|
||||
uint8 * p_end = p_data + len;
|
||||
|
||||
while (p_cur && p_cur < p_end && parse_len > 0)
|
||||
{
|
||||
uint8 * p_next = avc_split_nalu(p_cur, parse_len, &s_len, &n_len);
|
||||
|
||||
nalu_t = (p_cur[s_len] & 0x1F);
|
||||
|
||||
int b_start;
|
||||
nal_t nal;
|
||||
|
||||
nal.i_payload = n_len-s_len-1;
|
||||
nal.p_payload = p_cur+s_len+1;
|
||||
nal.i_type = nalu_t;
|
||||
|
||||
if (nalu_t == H264_NAL_SPS)
|
||||
{
|
||||
h264_t parse;
|
||||
h264_parser_init(&parse);
|
||||
|
||||
h264_parser_parse(&parse, &nal, &b_start);
|
||||
log_print(HT_LOG_INFO, "%s, H264 width[%d],height[%d]\r\n", __FUNCTION__, parse.i_width, parse.i_height);
|
||||
*width = parse.i_width;
|
||||
*height = parse.i_height;
|
||||
return 0;
|
||||
}
|
||||
|
||||
parse_len -= n_len;
|
||||
p_cur = p_next;
|
||||
}
|
||||
}
|
||||
else if (VIDEO_CODEC_H265 == codec)
|
||||
{
|
||||
int s_len, n_len = 0, parse_len = len;
|
||||
uint8 * p_cur = p_data;
|
||||
uint8 * p_end = p_data + len;
|
||||
|
||||
while (p_cur && p_cur < p_end && parse_len > 0)
|
||||
{
|
||||
uint8 * p_next = avc_split_nalu(p_cur, parse_len, &s_len, &n_len);
|
||||
|
||||
nalu_t = (p_cur[s_len] >> 1) & 0x3F;
|
||||
|
||||
if (nalu_t == HEVC_NAL_SPS)
|
||||
{
|
||||
h265_t parse;
|
||||
h265_parser_init(&parse);
|
||||
|
||||
if (h265_parser_parse(&parse, p_cur+s_len, n_len-s_len) == 0)
|
||||
{
|
||||
log_print(HT_LOG_INFO, "%s, H265 width[%d],height[%d]\r\n", __FUNCTION__, parse.pic_width_in_luma_samples, parse.pic_height_in_luma_samples);
|
||||
*width = parse.pic_width_in_luma_samples;
|
||||
*height = parse.pic_height_in_luma_samples;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
parse_len -= n_len;
|
||||
p_cur = p_next;
|
||||
}
|
||||
}
|
||||
else if (VIDEO_CODEC_JPEG == codec)
|
||||
{
|
||||
uint32 offset = 0;
|
||||
int size_chunk = 0;
|
||||
|
||||
while (offset < len - 8 && p_data[offset] == 0xFF)
|
||||
{
|
||||
if (p_data[offset+1] == MARKER_SOF0)
|
||||
{
|
||||
int h = ((p_data[offset+5] << 8) | p_data[offset+6]);
|
||||
int w = ((p_data[offset+7] << 8) | p_data[offset+8]);
|
||||
log_print(HT_LOG_INFO, "%s, MJPEG width[%d],height[%d]\r\n", __FUNCTION__, w, h);
|
||||
*width = w;
|
||||
*height = h;
|
||||
break;
|
||||
}
|
||||
else if (p_data[offset+1] == MARKER_SOI)
|
||||
{
|
||||
offset += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_chunk = ((p_data[offset+2] << 8) | p_data[offset+3]);
|
||||
offset += 2 + size_chunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (VIDEO_CODEC_MP4 == codec)
|
||||
{
|
||||
uint32 pos = 0;
|
||||
int vol_f = 0;
|
||||
int vol_pos = 0;
|
||||
int vol_len = 0;
|
||||
|
||||
while (pos < len - 4)
|
||||
{
|
||||
if (p_data[pos] == 0 && p_data[pos+1] == 0 && p_data[pos+2] == 1)
|
||||
{
|
||||
if (p_data[pos+3] >= 0x20 && p_data[pos+3] <= 0x2F)
|
||||
{
|
||||
vol_f = 1;
|
||||
vol_pos = pos+4;
|
||||
}
|
||||
else if (vol_f)
|
||||
{
|
||||
vol_len = pos - vol_pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (!vol_f)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (vol_len <= 0)
|
||||
{
|
||||
vol_len = len - vol_pos;
|
||||
}
|
||||
|
||||
int vo_ver_id = 0;
|
||||
|
||||
bs_t bs;
|
||||
bs_init(&bs, &p_data[vol_pos], vol_len * 8);
|
||||
|
||||
bs_skip(&bs, 1); /* random access */
|
||||
bs_skip(&bs, 8); /* vo_type */
|
||||
|
||||
if (bs_read1(&bs)) /* is_ol_id */
|
||||
{
|
||||
vo_ver_id = bs_read(&bs, 4); /* vo_ver_id */
|
||||
bs_skip(&bs, 3); /* vo_priority */
|
||||
}
|
||||
|
||||
if (bs_read(&bs, 4) == 15) // aspect_ratio_info
|
||||
{
|
||||
bs_skip(&bs, 8); // par_width
|
||||
bs_skip(&bs, 8); // par_height
|
||||
}
|
||||
|
||||
if (bs_read1(&bs)) /* vol control parameter */
|
||||
{
|
||||
bs_read(&bs, 2);
|
||||
|
||||
bs_skip(&bs, 1); /* low_delay */
|
||||
|
||||
if (bs_read1(&bs))
|
||||
{
|
||||
/* vbv parameters */
|
||||
bs_read(&bs, 15); /* first_half_bitrate */
|
||||
bs_skip(&bs, 1);
|
||||
bs_read(&bs, 15); /* latter_half_bitrate */
|
||||
bs_skip(&bs, 1);
|
||||
bs_read(&bs, 15); /* first_half_vbv_buffer_size */
|
||||
bs_skip(&bs, 1);
|
||||
bs_read(&bs, 3); /* latter_half_vbv_buffer_size */
|
||||
bs_read(&bs, 11); /* first_half_vbv_occupancy */
|
||||
bs_skip(&bs, 1);
|
||||
bs_read(&bs, 15); /* latter_half_vbv_occupancy */
|
||||
bs_skip(&bs, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int shape = bs_read(&bs, 2); /* vol shape */
|
||||
|
||||
if (shape == 3 && vo_ver_id != 1)
|
||||
{
|
||||
bs_skip(&bs, 4); /* video_object_layer_shape_extension */
|
||||
}
|
||||
|
||||
bs_skip(&bs, 1);
|
||||
|
||||
int framerate = bs_read(&bs, 16);
|
||||
|
||||
int time_increment_bits = (int) (log(framerate - 1.0) * 1.44269504088896340736 + 1); // log2(framerate - 1) + 1
|
||||
if (time_increment_bits < 1)
|
||||
{
|
||||
time_increment_bits = 1;
|
||||
}
|
||||
|
||||
bs_skip(&bs, 1);
|
||||
|
||||
if (bs_read1(&bs) != 0) /* fixed_vop_rate */
|
||||
{
|
||||
bs_skip(&bs, time_increment_bits);
|
||||
}
|
||||
|
||||
if (shape != 2)
|
||||
{
|
||||
if (shape == 0)
|
||||
{
|
||||
bs_skip(&bs, 1);
|
||||
int w = bs_read(&bs, 13);
|
||||
bs_skip(&bs, 1);
|
||||
int h = bs_read(&bs, 13);
|
||||
|
||||
log_print(HT_LOG_INFO, "%s, MPEG4 width[%d],height[%d]\r\n", __FUNCTION__, w, h);
|
||||
*width = w;
|
||||
*height = h;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user