/src/media_tools/av_parsers.c
C | 4542 lines | 3823 code | 483 blank | 236 comment | 965 complexity | 4d74b05e1a383deca7966dc5f407e1fd MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /*
- * GPAC - Multimedia Framework C SDK
- *
- * Authors: Jean Le Feuvre, Romain Bouqueau, Cyril Concolato
- * Copyright (c) Telecom ParisTech 2000-2012
- * All rights reserved
- *
- * This file is part of GPAC / Media Tools sub-project
- *
- * GPAC is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * GPAC is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
- #include "../../include/gpac/internal/media_dev.h"
- #include "../../include/gpac/constants.h"
- #include "../../include/gpac/mpeg4_odf.h"
- #ifndef GPAC_DISABLE_OGG
- #include "../../include/gpac/internal/ogg.h"
- #include "../../include/gpac/math.h"
- #endif
- static const struct { u32 w, h; } std_par[ ] =
- {
- { 4, 3}, {3, 2}, {16, 9}, {5, 3}, {5, 4}, {8, 5},
- {0, 0},
- };
- GF_EXPORT
- void gf_media_reduce_aspect_ratio(u32 *width, u32 *height)
- {
- u32 i=0;
- u32 w = *width;
- u32 h = *height;
- while (std_par[i].w) {
- if (std_par[i].w * h == std_par[i].h * w) {
- *width = std_par[i].w;
- *height = std_par[i].h;
- return;
- }
- i++;
- }
- }
- GF_EXPORT
- void gf_media_get_reduced_frame_rate(u32 *timescale, u32 *sample_dur)
- {
- u32 res;
- if (! *sample_dur) return;
- res = *timescale / *sample_dur;
- if (res * *sample_dur == *timescale) {
- *timescale = res;
- *sample_dur = 1;
- }
- }
- GF_EXPORT
- const char *gf_m4v_get_profile_name(u8 video_pl)
- {
- switch (video_pl) {
- case 0x00: return "Reserved (0x00) Profile";
- case 0x01: return "Simple Profile @ Level 1";
- case 0x02: return "Simple Profile @ Level 2";
- case 0x03: return "Simple Profile @ Level 3";
- case 0x08: return "Simple Profile @ Level 0";
- case 0x10: return "Simple Scalable Profile @ Level 0";
- case 0x11: return "Simple Scalable Profile @ Level 1";
- case 0x12: return "Simple Scalable Profile @ Level 2";
- case 0x15: return "AVC/H264 Profile";
- case 0x21: return "Core Profile @ Level 1";
- case 0x22: return "Core Profile @ Level 2";
- case 0x32: return "Main Profile @ Level 2";
- case 0x33: return "Main Profile @ Level 3";
- case 0x34: return "Main Profile @ Level 4";
- case 0x42: return "N-bit Profile @ Level 2";
- case 0x51: return "Scalable Texture Profile @ Level 1";
- case 0x61: return "Simple Face Animation Profile @ Level 1";
- case 0x62: return "Simple Face Animation Profile @ Level 2";
- case 0x63: return "Simple FBA Profile @ Level 1";
- case 0x64: return "Simple FBA Profile @ Level 2";
- case 0x71: return "Basic Animated Texture Profile @ Level 1";
- case 0x72: return "Basic Animated Texture Profile @ Level 2";
- case 0x81: return "Hybrid Profile @ Level 1";
- case 0x82: return "Hybrid Profile @ Level 2";
- case 0x91: return "Advanced Real Time Simple Profile @ Level 1";
- case 0x92: return "Advanced Real Time Simple Profile @ Level 2";
- case 0x93: return "Advanced Real Time Simple Profile @ Level 3";
- case 0x94: return "Advanced Real Time Simple Profile @ Level 4";
- case 0xA1: return "Core Scalable Profile @ Level1";
- case 0xA2: return "Core Scalable Profile @ Level2";
- case 0xA3: return "Core Scalable Profile @ Level3";
- case 0xB1: return "Advanced Coding Efficiency Profile @ Level 1";
- case 0xB2: return "Advanced Coding Efficiency Profile @ Level 2";
- case 0xB3: return "Advanced Coding Efficiency Profile @ Level 3";
- case 0xB4: return "Advanced Coding Efficiency Profile @ Level 4";
- case 0xC1: return "Advanced Core Profile @ Level 1";
- case 0xC2: return "Advanced Core Profile @ Level 2";
- case 0xD1: return "Advanced Scalable Texture @ Level1";
- case 0xD2: return "Advanced Scalable Texture @ Level2";
- case 0xE1: return "Simple Studio Profile @ Level 1";
- case 0xE2: return "Simple Studio Profile @ Level 2";
- case 0xE3: return "Simple Studio Profile @ Level 3";
- case 0xE4: return "Simple Studio Profile @ Level 4";
- case 0xE5: return "Core Studio Profile @ Level 1";
- case 0xE6: return "Core Studio Profile @ Level 2";
- case 0xE7: return "Core Studio Profile @ Level 3";
- case 0xE8: return "Core Studio Profile @ Level 4";
- case 0xF0: return "Advanced Simple Profile @ Level 0";
- case 0xF1: return "Advanced Simple Profile @ Level 1";
- case 0xF2: return "Advanced Simple Profile @ Level 2";
- case 0xF3: return "Advanced Simple Profile @ Level 3";
- case 0xF4: return "Advanced Simple Profile @ Level 4";
- case 0xF5: return "Advanced Simple Profile @ Level 5";
- case 0xF7: return "Advanced Simple Profile @ Level 3b";
- case 0xF8: return "Fine Granularity Scalable Profile @ Level 0";
- case 0xF9: return "Fine Granularity Scalable Profile @ Level 1";
- case 0xFA: return "Fine Granularity Scalable Profile @ Level 2";
- case 0xFB: return "Fine Granularity Scalable Profile @ Level 3";
- case 0xFC: return "Fine Granularity Scalable Profile @ Level 4";
- case 0xFD: return "Fine Granularity Scalable Profile @ Level 5";
- case 0xFE: return "Not part of MPEG-4 Visual profiles";
- case 0xFF: return "No visual capability required";
- default: return "ISO Reserved Profile";
- }
- }
- #ifndef GPAC_DISABLE_AV_PARSERS
- #define MPEG12_START_CODE_PREFIX 0x000001
- #define MPEG12_PICTURE_START_CODE 0x00000100
- #define MPEG12_SLICE_MIN_START 0x00000101
- #define MPEG12_SLICE_MAX_START 0x000001af
- #define MPEG12_USER_DATA_START_CODE 0x000001b2
- #define MPEG12_SEQUENCE_START_CODE 0x000001b3
- #define MPEG12_SEQUENCE_ERR_START_CODE 0x000001b4
- #define MPEG12_EXT_START_CODE 0x000001b5
- #define MPEG12_SEQUENCE_END_START_CODE 0x000001b7
- #define MPEG12_GOP_START_CODE 0x000001b8
- s32 gf_mv12_next_start_code(unsigned char *pbuffer, u32 buflen, u32 *optr, u32 *scode)
- {
- u32 value;
- u32 offset;
- if (buflen < 4) return -1;
- for (offset = 0; offset < buflen - 3; offset++, pbuffer++) {
- #ifdef GPAC_BIG_ENDIAN
- value = *(u32 *)pbuffer >> 8;
- #else
- value = (pbuffer[0] << 16) | (pbuffer[1] << 8) | (pbuffer[2] << 0);
- #endif
- if (value == MPEG12_START_CODE_PREFIX) {
- *optr = offset;
- *scode = (value << 8) | pbuffer[3];
- return 0;
- }
- }
- return -1;
- }
- s32 gf_mv12_next_slice_start(unsigned char *pbuffer, u32 startoffset, u32 buflen, u32 *slice_offset)
- {
- u32 slicestart, code;
- while (gf_mv12_next_start_code(pbuffer + startoffset, buflen - startoffset, &slicestart, &code) >= 0) {
- if ((code >= MPEG12_SLICE_MIN_START) && (code <= MPEG12_SLICE_MAX_START)) {
- *slice_offset = slicestart + startoffset;
- return 0;
- }
- startoffset += slicestart + 4;
- }
- return -1;
- }
- /*
- MPEG-4 video (14496-2)
- */
- #define M4V_VO_START_CODE 0x00
- #define M4V_VOL_START_CODE 0x20
- #define M4V_VOP_START_CODE 0xB6
- #define M4V_VISOBJ_START_CODE 0xB5
- #define M4V_VOS_START_CODE 0xB0
- #define M4V_GOV_START_CODE 0xB3
- #define M4V_UDTA_START_CODE 0xB2
- #define M2V_PIC_START_CODE 0x00
- #define M2V_SEQ_START_CODE 0xB3
- #define M2V_EXT_START_CODE 0xB5
- #define M2V_GOP_START_CODE 0xB8
- struct __tag_m4v_parser
- {
- GF_BitStream *bs;
- Bool mpeg12;
- u32 current_object_type;
- u64 current_object_start;
- u32 tc_dec, prev_tc_dec, tc_disp, prev_tc_disp;
- };
- GF_EXPORT
- GF_M4VParser *gf_m4v_parser_new(char *data, u64 data_size, Bool mpeg12video)
- {
- GF_M4VParser *tmp;
- if (!data || !data_size) return NULL;
- GF_SAFEALLOC(tmp, GF_M4VParser);
- tmp->bs = gf_bs_new(data, data_size, GF_BITSTREAM_READ);
- tmp->mpeg12 = mpeg12video;
- return tmp;
- }
- GF_M4VParser *gf_m4v_parser_bs_new(GF_BitStream *bs, Bool mpeg12video)
- {
- GF_M4VParser *tmp;
- GF_SAFEALLOC(tmp, GF_M4VParser);
- tmp->bs = bs;
- tmp->mpeg12 = mpeg12video;
- return tmp;
- }
- GF_EXPORT
- void gf_m4v_parser_del(GF_M4VParser *m4v)
- {
- gf_bs_del(m4v->bs);
- gf_free(m4v);
- }
- #define M4V_CACHE_SIZE 4096
- s32 M4V_LoadObject(GF_M4VParser *m4v)
- {
- u32 v, bpos, found;
- char m4v_cache[M4V_CACHE_SIZE];
- u64 end, cache_start, load_size;
- if (!m4v) return 0;
- bpos = 0;
- found = 0;
- load_size = 0;
- end = 0;
- cache_start = 0;
- v = 0xffffffff;
- while (!end) {
- /*refill cache*/
- if (bpos == (u32) load_size) {
- if (!gf_bs_available(m4v->bs)) break;
- load_size = gf_bs_available(m4v->bs);
- if (load_size>M4V_CACHE_SIZE) load_size=M4V_CACHE_SIZE;
- bpos = 0;
- cache_start = gf_bs_get_position(m4v->bs);
- gf_bs_read_data(m4v->bs, m4v_cache, (u32) load_size);
- }
- v = ( (v<<8) & 0xFFFFFF00) | ((u8) m4v_cache[bpos]);
- bpos++;
- if ((v & 0xFFFFFF00) == 0x00000100) {
- end = cache_start+bpos-4;
- found = 1;
- break;
- }
- }
- if (!found) return -1;
- m4v->current_object_start = end;
- gf_bs_seek(m4v->bs, end+3);
- m4v->current_object_type = gf_bs_read_u8(m4v->bs);
- return (s32) m4v->current_object_type;
- }
- GF_EXPORT
- void gf_m4v_rewrite_pl(char **o_data, u32 *o_dataLen, u8 PL)
- {
- u32 pos = 0;
- unsigned char *data = (unsigned char *)*o_data;
- u32 dataLen = *o_dataLen;
- while (pos+4<dataLen) {
- if (!data[pos] && !data[pos+1] && (data[pos+2]==0x01) && (data[pos+3]==M4V_VOS_START_CODE)) {
- data[pos+4] = PL;
- return;
- }
- pos ++;
- }
- /*emulate VOS at beggining*/
- (*o_data) = (char *)gf_malloc(sizeof(char)*(dataLen+5));
- (*o_data)[0] = 0;
- (*o_data)[1] = 0;
- (*o_data)[2] = 1;
- (*o_data)[3] = (char) M4V_VOS_START_CODE;
- (*o_data)[4] = PL;
- memcpy( (*o_data + 5), data, sizeof(char)*dataLen);
- gf_free(data);
- (*o_dataLen) = dataLen + 5;
- }
- static GF_Err M4V_Reset(GF_M4VParser *m4v, u64 start)
- {
- gf_bs_seek(m4v->bs, start);
- assert(start < 1<<31);
- m4v->current_object_start = (u32) start;
- m4v->current_object_type = 0;
- return GF_OK;
- }
- static GF_Err gf_m4v_parse_config_mpeg12(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi)
- {
- unsigned char p[4];
- u32 ext_type;
- s32 o_type;
- u8 go, par;
- if (!m4v || !dsi) return GF_BAD_PARAM;
- memset(dsi, 0, sizeof(GF_M4VDecSpecInfo));
- dsi->VideoPL = 0;
- go = 1;
- while (go) {
- o_type = M4V_LoadObject(m4v);
- switch (o_type) {
- case M2V_SEQ_START_CODE:
- dsi->RAP_stream = 1;
- gf_bs_read_data(m4v->bs, (char *) p, 4);
- dsi->width = (p[0] << 4) | ((p[1] >> 4) & 0xf);
- dsi->height = ((p[1] & 0xf) << 8) | p[2];
- dsi->VideoPL = GPAC_OTI_VIDEO_MPEG1;
- par = (p[3] >> 4) & 0xf;
- switch (par) {
- case 2: dsi->par_num = dsi->height/3; dsi->par_den = dsi->width/4; break;
- case 3: dsi->par_num = dsi->height/9; dsi->par_den = dsi->width/16; break;
- case 4: dsi->par_num = dsi->height/2; dsi->par_den = dsi->width/21; break;
- default: dsi->par_den = dsi->par_num = 0; break;
- }
- switch (p[3] & 0xf) {
- case 0: break;
- case 1: dsi->fps = 24000.0/1001.0; break;
- case 2: dsi->fps = 24.0; break;
- case 3: dsi->fps = 25.0; break;
- case 4: dsi->fps = 30000.0/1001.0; break;
- case 5: dsi->fps = 30.0; break;
- case 6: dsi->fps = 50.0; break;
- case 7: dsi->fps = ((60.0*1000.0)/1001.0); break;
- case 8: dsi->fps = 60.0; break;
- case 9: dsi->fps = 1; break;
- case 10: dsi->fps = 5; break;
- case 11: dsi->fps = 10; break;
- case 12: dsi->fps = 12; break;
- case 13: dsi->fps = 15; break;
- }
- break;
- case M2V_EXT_START_CODE:
- gf_bs_read_data(m4v->bs, (char *) p, 4);
- ext_type = ((p[0] >> 4) & 0xf);
- if (ext_type == 1) {
- dsi->VideoPL = 0x65;
- dsi->height = ((p[1] & 0x1) << 13) | ((p[2] & 0x80) << 5) | (dsi->height & 0x0fff);
- dsi->width = (((p[2] >> 5) & 0x3) << 12) | (dsi->width & 0x0fff);
- }
- break;
- case M2V_PIC_START_CODE:
- if (dsi->width) go = 0;
- break;
- default:
- break;
- /*EOS*/
- case -1:
- go = 0;
- m4v->current_object_start = gf_bs_get_position(m4v->bs);
- break;
- }
- }
- M4V_Reset(m4v, 0);
- return GF_OK;
- }
- static const struct { u32 w, h; } m4v_sar[6] = { { 0, 0 }, { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 }, { 40, 33 } };
- static u8 m4v_get_sar_idx(u32 w, u32 h)
- {
- u32 i;
- for (i=0; i<6; i++) {
- if ((m4v_sar[i].w==w) && (m4v_sar[i].h==h)) return i;
- }
- return 0xF;
- }
- static GF_Err gf_m4v_parse_config_mpeg4(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi)
- {
- s32 o_type;
- u8 go, verid, par;
- s32 clock_rate;
- if (!m4v || !dsi) return GF_BAD_PARAM;
- memset(dsi, 0, sizeof(GF_M4VDecSpecInfo));
- go = 1;
- while (go) {
- o_type = M4V_LoadObject(m4v);
- switch (o_type) {
- /*vosh*/
- case M4V_VOS_START_CODE:
- dsi->VideoPL = (u8) gf_bs_read_u8(m4v->bs);
- break;
- case M4V_VOL_START_CODE:
- verid = 0;
- dsi->RAP_stream = gf_bs_read_int(m4v->bs, 1);
- dsi->objectType = gf_bs_read_int(m4v->bs, 8);
- if (gf_bs_read_int(m4v->bs, 1)) {
- verid = gf_bs_read_int(m4v->bs, 4);
- gf_bs_read_int(m4v->bs, 3);
- }
- par = gf_bs_read_int(m4v->bs, 4);
- if (par == 0xF) {
- dsi->par_num = gf_bs_read_int(m4v->bs, 8);
- dsi->par_den = gf_bs_read_int(m4v->bs, 8);
- } else if (par<6) {
- dsi->par_num = m4v_sar[par].w;
- dsi->par_den = m4v_sar[par].h;
- }
- if (gf_bs_read_int(m4v->bs, 1)) {
- gf_bs_read_int(m4v->bs, 3);
- if (gf_bs_read_int(m4v->bs, 1)) gf_bs_read_int(m4v->bs, 79);
- }
- dsi->has_shape = gf_bs_read_int(m4v->bs, 2);
- if (dsi->has_shape && (verid!=1) ) gf_bs_read_int(m4v->bs, 4);
- gf_bs_read_int(m4v->bs, 1);
- /*clock rate*/
- dsi->clock_rate = gf_bs_read_int(m4v->bs, 16);
- /*marker*/
- gf_bs_read_int(m4v->bs, 1);
- clock_rate = dsi->clock_rate-1;
- if (clock_rate >= 65536) clock_rate = 65535;
- if (clock_rate > 0) {
- for (dsi->NumBitsTimeIncrement = 1; dsi->NumBitsTimeIncrement < 16; dsi->NumBitsTimeIncrement++) {
- if (clock_rate == 1) break;
- clock_rate = (clock_rate >> 1);
- }
- } else {
- /*fix from vivien for divX*/
- dsi->NumBitsTimeIncrement = 1;
- }
- /*fixed FPS stream*/
- dsi->time_increment = 0;
- if (gf_bs_read_int(m4v->bs, 1)) {
- dsi->time_increment = gf_bs_read_int(m4v->bs, dsi->NumBitsTimeIncrement);
- }
- if (!dsi->has_shape) {
- gf_bs_read_int(m4v->bs, 1);
- dsi->width = gf_bs_read_int(m4v->bs, 13);
- gf_bs_read_int(m4v->bs, 1);
- dsi->height = gf_bs_read_int(m4v->bs, 13);
- } else {
- dsi->width = dsi->height = 0;
- }
- /*shape will be done later*/
- gf_bs_align(m4v->bs);
- break;
- case M4V_VOP_START_CODE:
- case M4V_GOV_START_CODE:
- go = 0;
- break;
- /*EOS*/
- case -1:
- go = 0;
- m4v->current_object_start = gf_bs_get_position(m4v->bs);
- break;
- /*don't interest us*/
- case M4V_UDTA_START_CODE:
- default:
- break;
- }
- }
- return GF_OK;
- }
- GF_EXPORT
- GF_Err gf_m4v_parse_config(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi)
- {
- if (m4v->mpeg12) {
- return gf_m4v_parse_config_mpeg12(m4v, dsi);
- } else {
- return gf_m4v_parse_config_mpeg4(m4v, dsi);
- }
- }
- static GF_Err gf_m4v_parse_frame_mpeg12(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, u8 *frame_type, u32 *time_inc, u64 *size, u64 *start, Bool *is_coded)
- {
- u8 go, hasVOP, firstObj, val;
- s32 o_type;
- if (!m4v || !size || !start || !frame_type) return GF_BAD_PARAM;
- *size = 0;
- firstObj = 1;
- hasVOP = 0;
- *is_coded = 0;
- m4v->current_object_type = (u32) -1;
- *frame_type = 0;
- M4V_Reset(m4v, m4v->current_object_start);
- go = 1;
- while (go) {
- o_type = M4V_LoadObject(m4v);
- switch (o_type) {
- case M2V_PIC_START_CODE:
- /*done*/
- if (hasVOP) {
- go = 0;
- break;
- }
- if (firstObj) {
- *start = m4v->current_object_start;
- firstObj = 0;
- }
- hasVOP = 1;
- *is_coded = 1;
- val = gf_bs_read_u8(m4v->bs);
- val = gf_bs_read_u8(m4v->bs);
- *frame_type = ( (val >> 3) & 0x7 ) - 1;
- break;
- case M2V_GOP_START_CODE:
- if (firstObj) {
- *start = m4v->current_object_start;
- firstObj = 0;
- }
- if (hasVOP) go = 0;
- break;
- case M2V_SEQ_START_CODE:
- if (firstObj) {
- *start = m4v->current_object_start;
- firstObj = 0;
- }
- if (hasVOP) {
- go = 0;
- break;
- }
- /**/
- break;
- default:
- break;
- case -1:
- *size = gf_bs_get_position(m4v->bs) - *start;
- return GF_EOS;
- }
- }
- *size = m4v->current_object_start - *start;
- return GF_OK;
- }
- static GF_Err gf_m4v_parse_frame_mpeg4(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, u8 *frame_type, u32 *time_inc, u64 *size, u64 *start, Bool *is_coded)
- {
- u8 go, hasVOP, firstObj, secs;
- s32 o_type;
- u32 vop_inc = 0;
- if (!m4v || !size || !start || !frame_type) return GF_BAD_PARAM;
- *size = 0;
- firstObj = 1;
- hasVOP = 0;
- *is_coded = 0;
- m4v->current_object_type = (u32) -1;
- *frame_type = 0;
- M4V_Reset(m4v, m4v->current_object_start);
- go = 1;
- while (go) {
- o_type = M4V_LoadObject(m4v);
- switch (o_type) {
- case M4V_VOP_START_CODE:
- /*done*/
- if (hasVOP) {
- go = 0;
- break;
- }
- if (firstObj) {
- *start = m4v->current_object_start;
- firstObj = 0;
- }
- hasVOP = 1;
- /*coding type*/
- *frame_type = gf_bs_read_int(m4v->bs, 2);
- /*modulo time base*/
- secs = 0;
- while (gf_bs_read_int(m4v->bs, 1) != 0)
- secs ++;
- /*no support for B frames in parsing*/
- secs += (dsi.enh_layer || *frame_type!=2) ? m4v->tc_dec : m4v->tc_disp;
- /*marker*/
- gf_bs_read_int(m4v->bs, 1);
- /*vop_time_inc*/
- if (dsi.NumBitsTimeIncrement)
- vop_inc = gf_bs_read_int(m4v->bs, dsi.NumBitsTimeIncrement);
- m4v->prev_tc_dec = m4v->tc_dec;
- m4v->prev_tc_disp = m4v->tc_disp;
- if (dsi.enh_layer || *frame_type!=2) {
- m4v->tc_disp = m4v->tc_dec;
- m4v->tc_dec = secs;
- }
- *time_inc = secs * dsi.clock_rate + vop_inc;
- /*marker*/
- gf_bs_read_int(m4v->bs, 1);
- /*coded*/
- *is_coded = gf_bs_read_int(m4v->bs, 1);
- gf_bs_align(m4v->bs);
- break;
- case M4V_GOV_START_CODE:
- if (firstObj) {
- *start = m4v->current_object_start;
- firstObj = 0;
- }
- if (hasVOP) go = 0;
- break;
- case M4V_VOS_START_CODE:
- case M4V_VOL_START_CODE:
- if (hasVOP) {
- go = 0;
- } else if (firstObj) {
- *start = m4v->current_object_start;
- firstObj = 0;
- }
- break;
- case M4V_VO_START_CODE:
- default:
- break;
- case -1:
- *size = gf_bs_get_position(m4v->bs) - *start;
- return GF_EOS;
- }
- }
- *size = m4v->current_object_start - *start;
- return GF_OK;
- }
- GF_EXPORT
- GF_Err gf_m4v_parse_frame(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, u8 *frame_type, u32 *time_inc, u64 *size, u64 *start, Bool *is_coded)
- {
- if (m4v->mpeg12) {
- return gf_m4v_parse_frame_mpeg12(m4v, dsi, frame_type, time_inc, size, start, is_coded);
- } else {
- return gf_m4v_parse_frame_mpeg4(m4v, dsi, frame_type, time_inc, size, start, is_coded);
- }
- }
- GF_Err gf_m4v_rewrite_par(char **o_data, u32 *o_dataLen, s32 par_n, s32 par_d)
- {
- u64 start, end, size;
- GF_BitStream *mod;
- GF_M4VParser *m4v;
- Bool go = 1;
- m4v = gf_m4v_parser_new(*o_data, *o_dataLen, 0);
- mod = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
- end = start = 0;
- while (go) {
- u32 type = M4V_LoadObject(m4v);
- end = gf_bs_get_position(m4v->bs) - 4;
- size = end - start;
- /*store previous object*/
- if (size) {
- assert (size < 1<<31);
- if (size) gf_bs_write_data(mod, *o_data + start, (u32) size);
- start = end;
- }
- switch (type) {
- case M4V_VOL_START_CODE:
- gf_bs_write_int(mod, 0, 8);
- gf_bs_write_int(mod, 0, 8);
- gf_bs_write_int(mod, 1, 8);
- gf_bs_write_int(mod, M4V_VOL_START_CODE, 8);
- gf_bs_write_int(mod, gf_bs_read_int(m4v->bs, 1), 1);
- gf_bs_write_int(mod, gf_bs_read_int(m4v->bs, 8), 8);
- start = gf_bs_read_int(m4v->bs, 1);
- gf_bs_write_int(mod, (u32) start, 1);
- if (start) {
- gf_bs_write_int(mod, gf_bs_read_int(m4v->bs, 7), 7);
- }
- start = gf_bs_read_int(m4v->bs, 4);
- if (start == 0xF) {
- gf_bs_read_int(m4v->bs, 8);
- gf_bs_read_int(m4v->bs, 8);
- }
- if ((par_n>=0) && (par_d>=0)) {
- u8 par = m4v_get_sar_idx(par_n, par_d);
- gf_bs_write_int(mod, par, 4);
- if (par==0xF) {
- gf_bs_write_int(mod, par_n, 8);
- gf_bs_write_int(mod, par_d, 8);
- }
- } else {
- gf_bs_write_int(mod, 0x0, 4);
- }
- case -1:
- go = 0;
- break;
- default:
- break;
- }
- }
- while (gf_bs_bits_available(m4v->bs)) {
- u32 b = gf_bs_read_int(m4v->bs, 1);
- gf_bs_write_int(mod, b, 1);
- }
- gf_m4v_parser_del(m4v);
- gf_free(*o_data);
- gf_bs_get_content(mod, o_data, o_dataLen);
- gf_bs_del(mod);
- return GF_OK;
- }
- GF_EXPORT
- u64 gf_m4v_get_object_start(GF_M4VParser *m4v)
- {
- return m4v->current_object_start;
- }
- GF_EXPORT
- Bool gf_m4v_is_valid_object_type(GF_M4VParser *m4v)
- {
- return ((s32) m4v->current_object_type==-1) ? 0 : 1;
- }
- GF_EXPORT
- GF_Err gf_m4v_get_config(char *rawdsi, u32 rawdsi_size, GF_M4VDecSpecInfo *dsi)
- {
- GF_Err e;
- GF_M4VParser *vparse;
- if (!rawdsi || !rawdsi_size) return GF_NON_COMPLIANT_BITSTREAM;
- vparse = gf_m4v_parser_new(rawdsi, rawdsi_size, 0);
- e = gf_m4v_parse_config(vparse, dsi);
- gf_m4v_parser_del(vparse);
- return e;
- }
- #endif
- /*
- AAC parser
- */
- GF_EXPORT
- const char *gf_m4a_object_type_name(u32 objectType)
- {
- switch (objectType) {
- case 0: return "MPEG-4 Audio Reserved";
- case 1: return "MPEG-4 Audio AAC Main";
- case 2: return "MPEG-4 Audio AAC LC";
- case 3: return "MPEG-4 Audio AAC SSR";
- case 4: return "MPEG-4 Audio AAC LTP";
- case 5: return "MPEG-4 Audio SBR";
- case 6: return "MPEG-4 Audio AAC Scalable";
- case 7: return "MPEG-4 Audio TwinVQ";
- case 8: return "MPEG-4 Audio CELP";
- case 9: return "MPEG-4 Audio HVXC";
- case 10: return "MPEG-4 Audio Reserved";
- case 11: return "MPEG-4 Audio Reserved";
- case 12: return "MPEG-4 Audio TTSI";
- case 13: return "MPEG-4 Audio Main synthetic";
- case 14: return "MPEG-4 Audio Wavetable synthesis";
- case 15: return "MPEG-4 Audio General MIDI";
- case 16: return "MPEG-4 Audio Algorithmic Synthesis and Audio FX";
- case 17: return "MPEG-4 Audio ER AAC LC";
- case 18: return "MPEG-4 Audio Reserved";
- case 19: return "MPEG-4 Audio ER AAC LTP";
- case 20: return "MPEG-4 Audio ER AAC scalable";
- case 21: return "MPEG-4 Audio ER TwinVQ";
- case 22: return "MPEG-4 Audio ER BSAC";
- case 23: return "MPEG-4 Audio ER AAC LD";
- case 24: return "MPEG-4 Audio ER CELP";
- case 25: return "MPEG-4 Audio ER HVXC";
- case 26: return "MPEG-4 Audio ER HILN";
- case 27: return "MPEG-4 Audio ER Parametric";
- case 28: return "MPEG-4 Audio SSC";
- case 29: return "MPEG-4 Audio ParametricStereo";
- case 30: return "MPEG-4 Audio Reserved";
- case 31: return "MPEG-4 Audio Reserved";
- case 32: return "MPEG-1 Audio Layer-1";
- case 33: return "MPEG-1 Audio Layer-2";
- case 34: return "MPEG-1 Audio Layer-3";
- case 35: return "MPEG-4 Audio DST";
- case 36: return "MPEG-4 Audio ALS";
- case 37: return "MPEG-4 Audio SLS";
- default: return "MPEG-4 Audio Unknown";
- }
- }
- GF_EXPORT
- const char *gf_m4a_get_profile_name(u8 audio_pl)
- {
- switch (audio_pl) {
- case 0x00: return "ISO Reserved (0x00)";
- case 0x01: return "Main Audio Profile @ Level 1";
- case 0x02: return "Main Audio Profile @ Level 2";
- case 0x03: return "Main Audio Profile @ Level 3";
- case 0x04: return "Main Audio Profile @ Level 4";
- case 0x05: return "Scalable Audio Profile @ Level 1";
- case 0x06: return "Scalable Audio Profile @ Level 2";
- case 0x07: return "Scalable Audio Profile @ Level 3";
- case 0x08: return "Scalable Audio Profile @ Level 4";
- case 0x09: return "Speech Audio Profile @ Level 1";
- case 0x0A: return "Speech Audio Profile @ Level 2";
- case 0x0B: return "Synthetic Audio Profile @ Level 1";
- case 0x0C: return "Synthetic Audio Profile @ Level 2";
- case 0x0D: return "Synthetic Audio Profile @ Level 3";
- case 0x0E: return "High Quality Audio Profile @ Level 1";
- case 0x0F: return "High Quality Audio Profile @ Level 2";
- case 0x10: return "High Quality Audio Profile @ Level 3";
- case 0x11: return "High Quality Audio Profile @ Level 4";
- case 0x12: return "High Quality Audio Profile @ Level 5";
- case 0x13: return "High Quality Audio Profile @ Level 6";
- case 0x14: return "High Quality Audio Profile @ Level 7";
- case 0x15: return "High Quality Audio Profile @ Level 8";
- case 0x16: return "Low Delay Audio Profile @ Level 1";
- case 0x17: return "Low Delay Audio Profile @ Level 2";
- case 0x18: return "Low Delay Audio Profile @ Level 3";
- case 0x19: return "Low Delay Audio Profile @ Level 4";
- case 0x1A: return "Low Delay Audio Profile @ Level 5";
- case 0x1B: return "Low Delay Audio Profile @ Level 6";
- case 0x1C: return "Low Delay Audio Profile @ Level 7";
- case 0x1D: return "Low Delay Audio Profile @ Level 8";
- case 0x1E: return "Natural Audio Profile @ Level 1";
- case 0x1F: return "Natural Audio Profile @ Level 2";
- case 0x20: return "Natural Audio Profile @ Level 3";
- case 0x21: return "Natural Audio Profile @ Level 4";
- case 0x22: return "Mobile Audio Internetworking Profile @ Level 1";
- case 0x23: return "Mobile Audio Internetworking Profile @ Level 2";
- case 0x24: return "Mobile Audio Internetworking Profile @ Level 3";
- case 0x25: return "Mobile Audio Internetworking Profile @ Level 4";
- case 0x26: return "Mobile Audio Internetworking Profile @ Level 5";
- case 0x27: return "Mobile Audio Internetworking Profile @ Level 6";
- case 0x28: return "AAC Profile @ Level 1";
- case 0x29: return "AAC Profile @ Level 2";
- case 0x2A: return "AAC Profile @ Level 4";
- case 0x2B: return "AAC Profile @ Level 5";
- case 0x2C: return "High Efficiency AAC Profile @ Level 2";
- case 0x2D: return "High Efficiency AAC Profile @ Level 3";
- case 0x2E: return "High Efficiency AAC Profile @ Level 4";
- case 0x2F: return "High Efficiency AAC Profile @ Level 5";
- case 0x3B: return "High Definition AAC Profile @ Level 1";
- case 0x3C: return "ALS Simple Profile @ Level 1";
- case 0xFE: return "Not part of MPEG-4 audio profiles";
- case 0xFF: return "No audio capability required";
- default: return "ISO Reserved / User Private";
- }
- }
- #ifndef GPAC_DISABLE_AV_PARSERS
- GF_EXPORT
- u32 gf_m4a_get_profile(GF_M4ADecSpecInfo *cfg)
- {
- switch (cfg->base_object_type) {
- case 2: /*AAC LC*/
- if (cfg->nb_chan<=2) return (cfg->base_sr<=24000) ? 0x28 : 0x29; /*LC@L1 or LC@L2*/
- return (cfg->base_sr<=48000) ? 0x2A : 0x2B; /*LC@L4 or LC@L5*/
- case 5: /*HE-AAC - SBR*/
- case 29: /*HE-AAC - SBR+PS*/
- if (cfg->nb_chan<=2) return (cfg->base_sr<=24000) ? 0x2C : 0x2D; /*HE@L2 or HE@L3*/
- return (cfg->base_sr<=48000) ? 0x2E : 0x2F; /*HE@L4 or HE@L5*/
- /*default to HQ*/
- default:
- if (cfg->nb_chan<=2) return (cfg->base_sr<24000) ? 0x0E : 0x0F; /*HQ@L1 or HQ@L2*/
- return 0x10; /*HQ@L3*/
- }
- }
- GF_EXPORT
- GF_Err gf_m4a_parse_config(GF_BitStream *bs, GF_M4ADecSpecInfo *cfg, Bool size_known)
- {
- memset(cfg, 0, sizeof(GF_M4ADecSpecInfo));
- cfg->base_object_type = gf_bs_read_int(bs, 5);
- /*extended object type*/
- if (cfg->base_object_type==31) {
- cfg->base_object_type = 32 + gf_bs_read_int(bs, 6);
- }
- cfg->base_sr_index = gf_bs_read_int(bs, 4);
- if (cfg->base_sr_index == 0x0F) {
- cfg->base_sr = gf_bs_read_int(bs, 24);
- } else {
- cfg->base_sr = GF_M4ASampleRates[cfg->base_sr_index];
- }
- cfg->nb_chan = gf_bs_read_int(bs, 4);
- /*this is 7+1 channels*/
- if (cfg->nb_chan==7) cfg->nb_chan=8;
- if (cfg->base_object_type==5 || cfg->base_object_type==29) {
- if (cfg->base_object_type==29) {
- cfg->has_ps = 1;
- cfg->nb_chan = 1;
- }
- cfg->has_sbr = 1;
- cfg->sbr_sr_index = gf_bs_read_int(bs, 4);
- if (cfg->sbr_sr_index == 0x0F) {
- cfg->sbr_sr = gf_bs_read_int(bs, 24);
- } else {
- cfg->sbr_sr = GF_M4ASampleRates[cfg->sbr_sr_index];
- }
- cfg->sbr_object_type = gf_bs_read_int(bs, 5);
- }
- /*object cfg*/
- switch (cfg->base_object_type) {
- case 1:
- case 2:
- case 3:
- case 4:
- case 6:
- case 7:
- case 17:
- case 19:
- case 20:
- case 21:
- case 22:
- case 23:
- {
- Bool ext_flag;
- /*frame length flag*/
- /*fl_flag = */gf_bs_read_int(bs, 1);
- /*depends on core coder*/
- if (gf_bs_read_int(bs, 1))
- /*delay = */gf_bs_read_int(bs, 14);
- ext_flag = gf_bs_read_int(bs, 1);
- if (!cfg->nb_chan) {
- }
- if ((cfg->base_object_type == 6) || (cfg->base_object_type == 20)) {
- gf_bs_read_int(bs, 3);
- }
- if (ext_flag) {
- if (cfg->base_object_type == 22) {
- gf_bs_read_int(bs, 5);
- gf_bs_read_int(bs, 11);
- }
- if ((cfg->base_object_type == 17)
- || (cfg->base_object_type == 19)
- || (cfg->base_object_type == 20)
- || (cfg->base_object_type == 23)
- ) {
- gf_bs_read_int(bs, 1);
- gf_bs_read_int(bs, 1);
- gf_bs_read_int(bs, 1);
- }
- ext_flag = gf_bs_read_int(bs, 1);
- }
- }
- break;
- }
- /*ER cfg*/
- switch (cfg->base_object_type) {
- case 17:
- case 19:
- case 20:
- case 21:
- case 22:
- case 23:
- case 24:
- case 25:
- case 26:
- case 27:
- {
- u32 epConfig = gf_bs_read_int(bs, 2);
- if ((epConfig == 2) || (epConfig == 3) ) {
- }
- if (epConfig == 3) {
- gf_bs_read_int(bs, 1);
- }
- }
- break;
- }
- if (size_known && (cfg->base_object_type != 5) && (cfg->base_object_type != 29) ) {
- while (gf_bs_available(bs)>=2) {
- u32 sync = gf_bs_peek_bits(bs, 11, 0);
- if (sync==0x2b7) {
- gf_bs_read_int(bs, 11);
- cfg->sbr_object_type = gf_bs_read_int(bs, 5);
- cfg->has_sbr = gf_bs_read_int(bs, 1);
- if (cfg->has_sbr) {
- cfg->sbr_sr_index = gf_bs_read_int(bs, 4);
- if (cfg->sbr_sr_index == 0x0F) {
- cfg->sbr_sr = gf_bs_read_int(bs, 24);
- } else {
- cfg->sbr_sr = GF_M4ASampleRates[cfg->sbr_sr_index];
- }
- }
- } else if (sync == 0x548) {
- gf_bs_read_int(bs, 11);
- cfg->has_ps = gf_bs_read_int(bs, 1);
- if (cfg->has_ps)
- cfg->nb_chan = 1;
- } else {
- break;
- }
- }
- }
- cfg->audioPL = gf_m4a_get_profile(cfg);
- return GF_OK;
- }
- GF_EXPORT
- GF_Err gf_m4a_get_config(char *dsi, u32 dsi_size, GF_M4ADecSpecInfo *cfg)
- {
- GF_BitStream *bs;
- if (!dsi || !dsi_size || (dsi_size<2) ) return GF_NON_COMPLIANT_BITSTREAM;
- bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ);
- gf_m4a_parse_config(bs, cfg, 1);
- gf_bs_del(bs);
- return GF_OK;
- }
- u32 gf_latm_get_value(GF_BitStream *bs)
- {
- u32 i, tmp, value = 0;
- u32 bytesForValue = gf_bs_read_int(bs, 2);
- for (i=0; i <= bytesForValue; i++) {
- value <<= 8;
- tmp = gf_bs_read_int(bs, 8);
- value += tmp;
- }
- return value;
- }
- GF_EXPORT
- GF_Err gf_m4a_write_config_bs(GF_BitStream *bs, GF_M4ADecSpecInfo *cfg)
- {
- if (!cfg->base_sr_index) {
- if (!cfg->base_sr) return GF_BAD_PARAM;
- while (GF_M4ASampleRates[cfg->base_sr_index]) {
- if (GF_M4ASampleRates[cfg->base_sr_index]==cfg->base_sr)
- break;
- cfg->base_sr_index++;
- }
- }
- if (cfg->sbr_sr && !cfg->sbr_sr_index) {
- while (GF_M4ASampleRates[cfg->sbr_sr_index]) {
- if (GF_M4ASampleRates[cfg->sbr_sr_index]==cfg->sbr_sr)
- break;
- cfg->sbr_sr_index++;
- }
- }
- /*extended object type*/
- if (cfg->base_object_type>=32) {
- gf_bs_write_int(bs, 31, 5);
- gf_bs_write_int(bs, cfg->base_object_type-32, 6);
- } else {
- gf_bs_write_int(bs, cfg->base_object_type, 5);
- }
- gf_bs_write_int(bs, cfg->base_sr_index, 4);
- if (cfg->base_sr_index == 0x0F) {
- gf_bs_write_int(bs, cfg->base_sr, 24);
- }
- if (cfg->nb_chan == 8) {
- gf_bs_write_int(bs, 7, 4);
- } else {
- gf_bs_write_int(bs, cfg->nb_chan, 4);
- }
- if (cfg->base_object_type==5 || cfg->base_object_type==29) {
- if (cfg->base_object_type == 29) {
- cfg->has_ps = 1;
- cfg->nb_chan = 1;
- }
- cfg->has_sbr = 1;
- gf_bs_write_int(bs, cfg->sbr_sr_index, 4);
- if (cfg->sbr_sr_index == 0x0F) {
- gf_bs_write_int(bs, cfg->sbr_sr, 24);
- }
- gf_bs_write_int(bs, cfg->sbr_object_type, 5);
- }
- /*object cfg*/
- switch (cfg->base_object_type) {
- case 1:
- case 2:
- case 3:
- case 4:
- case 6:
- case 7:
- case 17:
- case 19:
- case 20:
- case 21:
- case 22:
- case 23:
- {
- /*frame length flag*/
- gf_bs_write_int(bs, 0, 1);
- /*depends on core coder*/
- gf_bs_write_int(bs, 0, 1);
- /*ext flag*/
- gf_bs_write_int(bs, 0, 1);
- if ((cfg->base_object_type == 6) || (cfg->base_object_type == 20)) {
- gf_bs_write_int(bs, 0, 3);
- }
- }
- break;
- }
- /*ER cfg - not supported*/
- /*implicit sbr - not used yet*/
- if (0 && (cfg->base_object_type != 5) && (cfg->base_object_type != 29) ) {
- gf_bs_write_int(bs, 0x2b7, 11);
- cfg->sbr_object_type = gf_bs_read_int(bs, 5);
- cfg->has_sbr = gf_bs_read_int(bs, 1);
- if (cfg->has_sbr) {
- cfg->sbr_sr_index = gf_bs_read_int(bs, 4);
- if (cfg->sbr_sr_index == 0x0F) {
- cfg->sbr_sr = gf_bs_read_int(bs, 24);
- } else {
- cfg->sbr_sr = GF_M4ASampleRates[cfg->sbr_sr_index];
- }
- }
- }
- return GF_OK;
- }
- GF_EXPORT
- GF_Err gf_m4a_write_config(GF_M4ADecSpecInfo *cfg, char **dsi, u32 *dsi_size)
- {
- GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
- gf_m4a_write_config_bs(bs, cfg);
- gf_bs_get_content(bs, dsi, dsi_size);
- gf_bs_del(bs);
- return GF_OK;
- }
- #endif /*GPAC_DISABLE_AV_PARSERS*/
- GF_EXPORT
- u8 gf_mp3_version(u32 hdr)
- {
- return ((hdr >> 19) & 0x3);
- }
- GF_EXPORT
- const char *gf_mp3_version_name(u32 hdr)
- {
- u32 v = gf_mp3_version(hdr);
- switch (v) {
- case 0: return "MPEG-2.5";
- case 1: return "Reserved";
- case 2: return "MPEG-2";
- case 3: return "MPEG-1";
- default: return "Unknown";
- }
- }
- #ifndef GPAC_DISABLE_AV_PARSERS
- GF_EXPORT
- u8 gf_mp3_layer(u32 hdr)
- {
- return 4 - (((hdr >> 17) & 0x3));
- }
- GF_EXPORT
- u8 gf_mp3_num_channels(u32 hdr)
- {
- if (((hdr >> 6) & 0x3) == 3) return 1;
- return 2;
- }
- GF_EXPORT
- u16 gf_mp3_sampling_rate(u32 hdr)
- {
- u16 res;
- /* extract the necessary fields from the MP3 header */
- u8 version = gf_mp3_version(hdr);
- u8 sampleRateIndex = (hdr >> 10) & 0x3;
- switch (sampleRateIndex) {
- case 0:
- res = 44100;
- break;
- case 1:
- res = 48000;
- break;
- case 2:
- res = 32000;
- break;
- default:
- GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[MPEG-1/2 Audio] Samplerate index not valid\n"));
- return 0;
- }
- /*reserved or MPEG-1*/
- if (version & 1) return res;
- /*MPEG-2*/
- res /= 2;
- /*MPEG-2.5*/
- if (version == 0) res /= 2;
- return res;
- }
- GF_EXPORT
- u16 gf_mp3_window_size(u32 hdr)
- {
- u8 version = gf_mp3_version(hdr);
- u8 layer = gf_mp3_layer(hdr);
- if (layer == 3) {
- if (version == 3) return 1152;
- return 576;
- }
- if (layer == 2) return 1152;
- return 384;
- }
- GF_EXPORT
- u8 gf_mp3_object_type_indication(u32 hdr)
- {
- switch (gf_mp3_version(hdr)) {
- case 3:
- return GPAC_OTI_AUDIO_MPEG1;
- case 2:
- case 0:
- return GPAC_OTI_AUDIO_MPEG2_PART3;
- default:
- return 0x00;
- }
- }
- /*aligned bitrate parsing with libMAD*/
- static
- u32 const bitrate_table[5][15] = {
- /* MPEG-1 */
- { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */
- 256000, 288000, 320000, 352000, 384000, 416000, 448000 },
- { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */
- 128000, 160000, 192000, 224000, 256000, 320000, 384000 },
- { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */
- 112000, 128000, 160000, 192000, 224000, 256000, 320000 },
- /* MPEG-2 LSF */
- { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */
- 128000, 144000, 160000, 176000, 192000, 224000, 256000 },
- { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */
- 64000, 80000, 96000, 112000, 128000, 144000, 160000 } /* II & III */
- };
- u32 gf_mp3_bit_rate(u32 hdr)
- {
- u8 version = gf_mp3_version(hdr);
- u8 layer = gf_mp3_layer(hdr);
- u8 bitRateIndex = (hdr >> 12) & 0xF;
- if (bitRateIndex == 15) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[MPEG-1/2 Audio] Bitrate index not valid\n"));
- return 0;
- }
- /*MPEG-1*/
- if (version & 1)
- return bitrate_table[layer - 1][bitRateIndex];
- /*MPEG-2/2.5*/
- else
- return bitrate_table[3 + (layer >> 1)][bitRateIndex];
- }
- GF_EXPORT
- u16 gf_mp3_frame_size(u32 hdr)
- {
- u8 version = gf_mp3_version(hdr);
- u8 layer = gf_mp3_layer(hdr);
- u32 pad = ( (hdr >> 9) & 0x1) ? 1 : 0;
- u32 bitrate = gf_mp3_bit_rate(hdr);
- u32 samplerate = gf_mp3_sampling_rate(hdr);
- u32 frameSize = 0;
- if (!samplerate || !bitrate) return 0;
- if (layer==1) {
- frameSize = (( 12 * bitrate / samplerate) + pad) * 4;
- } else {
- u32 slots_per_frame = 144;
- if ((layer == 3) && !(version & 1)) slots_per_frame = 72;
- frameSize = (slots_per_frame * bitrate / samplerate) + pad;
- }
- return (u16) frameSize;
- }
- GF_EXPORT
- u32 gf_mp3_get_next_header(FILE* in)
- {
- u8 b, state = 0;
- u32 dropped = 0;
- unsigned char bytes[4];
- bytes[0] = bytes[1] = bytes[2] = bytes[3] = 0;
- while (1) {
- if (fread(&b, 1, 1, in) == 0) return 0;
- if (state==3) {
- bytes[state] = b;
- return GF_4CC(bytes[0], bytes[1], bytes[2], bytes[3]);
- }
- if (state==2) {
- if (((b & 0xF0) == 0) || ((b & 0xF0) == 0xF0) || ((b & 0x0C) == 0x0C)) {
- if (bytes[1] == 0xFF) state = 1;
- else state = 0;
- } else {
- bytes[state] = b;
- state = 3;
- }
- }
- if (state==1) {
- if (((b & 0xE0) == 0xE0) && ((b & 0x18) != 0x08) && ((b & 0x06) != 0)) {
- bytes[state] = b;
- state = 2;
- } else {
- state = 0;
- }
- }
- if (state==0) {
- if (b == 0xFF) {
- bytes[state] = b;
- state = 1;
- } else {
- if ((dropped == 0) && ((b & 0xE0) == 0xE0) && ((b & 0x18) != 0x08) && ((b & 0x06) != 0)) {
- bytes[0] = (u8) 0xFF;
- bytes[1] = b;
- state = 2;
- } else {
- dropped++;
- }
- }
- }
- }
- return 0;
- }
- GF_EXPORT
- u32 gf_mp3_get_next_header_mem(const char *buffer, u32 size, u32 *pos)
- {
- u32 cur;
- u8 b, state = 0;
- u32 dropped = 0;
- unsigned char bytes[4];
- bytes[0] = bytes[1] = bytes[2] = bytes[3] = 0;
- cur = 0;
- *pos = 0;
- while (cur<size) {
- b = (u8) buffer[cur];
- cur++;
- if (state==3) {
- u32 val;
- bytes[state] = b;
- val = GF_4CC(bytes[0], bytes[1], bytes[2], bytes[3]);
- if (gf_mp3_frame_size(val)) {
- *pos = dropped;
- return val;
- }
- state = 0;
- dropped = cur;
- }
- if (state==2) {
- if (((b & 0xF0) == 0) || ((b & 0xF0) == 0xF0) || ((b & 0x0C) == 0x0C)) {
- if (bytes[1] == 0xFF) {
- state = 1;
- dropped+=1;
- } else {
- state = 0;
- dropped = cur;
- }
- } else {
- bytes[state] = b;
- state = 3;
- }
- }
- if (state==1) {
- if (((b & 0xE0) == 0xE0) && ((b & 0x18) != 0x08) && ((b & 0x06) != 0)) {
- bytes[state] = b;
- state = 2;
- } else {
- state = 0;
- dropped = cur;
- }
- }
- if (state==0) {
- if (b == 0xFF) {
- bytes[state] = b;
- state = 1;
- } else {
- dropped++;
- }
- }
- }
- return 0;
- }
- #endif /*GPAC_DISABLE_AV_PARSERS*/
- GF_EXPORT
- const char *gf_avc_get_profile_name(u8 video_prof)
- {
- switch (video_prof) {
- case 0x42: return "Baseline";
- case 0x4D: return "Main";
- case 0x53: return "Scalable Baseline";
- case 0x56: return "Scalable High";
- case 0x58: return "Extended";
- case 0x64: return "High";
- case 0x6E: return "High 10";
- case 0x7A: return "High 4:2:2";
- case 0x90: return "High 4:4:4";
- default: return "Unknown";
- }
- }
- #ifndef GPAC_DISABLE_AV_PARSERS
- static u8 avc_golomb_bits[256] = {
- 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0
- };
- static u32 bs_get_ue(GF_BitStream *bs)
- {
- u8 coded;
- u32 bits = 0, read = 0;
- while (1) {
- read = gf_bs_peek_bits(bs, 8, 0);
- if (read) break;
- //check whether we still have bits once the peek is done since we may have less than 8 bits available
- if (!gf_bs_available(bs)) {
- GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AVC/HEVC] Not enough bits in bitstream !!\n"));
- return 0;
- }
- gf_bs_read_int(bs, 8);
- bits += 8;
- }
- coded = avc_golomb_bits[read];
- gf_bs_read_int(bs, coded);
- bits += coded;
- return gf_bs_read_int(bs, bits + 1) - 1;
- }
- static s32 bs_get_se(GF_BitStream *bs)
- {
- u32 v = bs_get_ue(bs);
- if ((v & 0x1) == 0) return (s32) (0 - (v>>1));
- return (v + 1) >> 1;
- }
- u32 gf_media_nalu_is_start_code(GF_BitStream *bs)
- {
- u8 s1, s2, s3, s4;
- Bool is_sc = 0;
- u64 pos = gf_bs_get_position(bs);
- s1 = gf_bs_read_int(bs, 8);
- s2 = gf_bs_read_int(bs, 8);
- if (!s1 && !s2) {
- s3 = gf_bs_read_int(bs, 8);
- if (s3==0x01) is_sc = 3;
- else if (!s3) {
- s4 = gf_bs_read_int(bs, 8);
- if (s4==0x01) is_sc = 4;
- }
- }
- gf_bs_seek(bs, pos+is_sc);
- return is_sc;
- }
- /*read that amount of data at each IO access rather than fetching byte by byte...*/
- #define AVC_CACHE_SIZE 4096
- GF_EXPORT
- u32 gf_media_nalu_next_start_code_bs(GF_BitStream *bs)
- {
- u32 v, bpos;
- char avc_cache[AVC_CACHE_SIZE];
- u64 end, cache_start, load_size;
- u64 start = gf_bs_get_position(bs);
- if (start<3) return 0;
- load_size = 0;
- bpos = 0;
- cache_start = 0;
- end = 0;
- v = 0xffffffff;
- while (!end) {
- /*refill cache*/
- if (bpos == (u32) load_size) {
- if (!gf_bs_available(bs)) break;
- load_size = gf_bs_available(bs);
- if (load_size>AVC_CACHE_SIZE) load_size=AVC_CACHE_SIZE;
- bpos = 0;
- cache_start = gf_bs_get_position(bs);
- gf_bs_read_data(bs, avc_cache, (u32) load_size);
- }
- v = ( (v<<8) & 0xFFFFFF00) | ((u32) avc_cache[bpos]);
- bpos++;
- if (v == 0x00000001) end = cache_start+bpos-4;
- else if ( (v & 0x00FFFFFF) == 0x00000001) end = cache_start+bpos-3;
- }
- gf_bs_seek(bs, start);
- if (!end) end = gf_bs_get_size(bs);
- return (u32) (end-start);
- }
- GF_EXPORT
- u32 gf_media_nalu_next_start_code(u8 *data, u32 data_len, u32 *sc_size)
- {
- u32 v, bpos;
- u32 end;
- bpos = 0;
- end = 0;
- v = 0xffffffff;
- while (!end) {
- /*refill cache*/
- if (bpos == (u32) data_len)
- break;
- v = ( (v<<8) & 0xFFFFFF00) | ((u32) data[bpos]);
- bpos++;
- if (v == 0x00000001) {
- end = bpos-4;
- *sc_size = 4;
- return end;
- }
- else if ( (v & 0x00FFFFFF) == 0x00000001) {
- end = bpos-3;
- *sc_size = 3;
- return end;
- }
- }
- if (!end) end = data_len;
- return (u32) (end);
- }
- Bool gf_media_avc_slice_is_intra(AVCState *avc)
- {
- switch (avc->s_info.slice_type) {
- case GF_AVC_TYPE_I:
- case GF_AVC_TYPE2_I:
- case GF_AVC_TYPE_SI:
- case GF_AVC_TYPE2_SI:
- return 1;
- default:
- return 0;
- }
- }
- Bool gf_media_avc_slice_is_IDR(AVCState *avc)
- {
- if (avc->sei.recovery_point.valid)
- {
- avc->sei.recovery_point.valid = 0;
- return 1;
- }
- if (avc->s_info.nal_unit_type != GF_AVC_NALU_IDR_SLICE)
- return 0;
- return gf_media_avc_slice_is_intra(avc);
- }
- static const struct { u32 w, h; } avc_sar[14] =
- {
- { 0, 0 }, { 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 },
- };
- /*ISO 14496-10 (N11084) E.1.2*/
- static void avc_parse_hrd_parameters(GF_BitStream *bs, AVC_HRD *hrd)
- {
- int i, cpb_cnt_minus1;
- cpb_cnt_minus1 = bs_get_ue(bs); /*cpb_cnt_minus1*/
- if (cpb_cnt_minus1 > 31)
- GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[avc-h264] invalid cpb_cnt_minus1 value: %d (expected in [0;31])\n", cpb_cnt_minus1));
- gf_bs_read_int(bs, 4); /*bit_rate_scale*/
- gf_bs_read_int(bs, 4); /*cpb_size_scale*/
- /*for( SchedSelIdx = 0; SchedSelIdx <= cpb_cnt_minus1; SchedSelIdx++ ) {*/
- for (i=0; i<=cpb_cnt_minus1; i++) {
- bs_get_ue(bs); /*bit_rate_value_minus1[ SchedSelIdx ]*/
- bs_get_ue(bs); /*cpb_size_value_minus1[ SchedSelIdx ]*/
- gf_bs_read_int(bs, 1); /*cbr_flag[ SchedSelIdx ]*/
- }
- gf_bs_read_int(bs, 5); /*initial_cpb_removal_delay_length_minus1*/
- hrd->cpb_removal_delay_length_minus1 = gf_bs_read_int(bs, 5); /*cpb_removal_delay_length_minus1*/
- hrd->dpb_output_delay_length_minus1 = gf_bs_read_int(bs, 5); /*dpb_output_delay_length_minus1*/
- hrd->time_offset_length = gf_bs_read_int(bs, 5); /*time_offset_length*/
- return;
- }
- /*returns the nal_size without emulation prevention bytes*/
- static u32 avc_emulation_bytes_add_count(char *buffer, u32 nal_size)
- {
- u32 i = 0, emulation_bytes_count = 0;
- u8 num_zero = 0;
- while (i < nal_size) {
- /*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003
- other than the following sequences shall not occur at any byte-aligned position:
- \96 0x00000300
- \96 0x00000301
- \96 0x00000302
- \96 0x00000303"
- */
- if (num_zero == 2 && buffer[i] < 0x04) {
- /*emulation code found*/
- num_zero = 0;
- emulation_bytes_count++;
- } else {
- if (!buffer[i])
- num_zero++;
- else
- num_zero = 0;
- }
- i++;
- }
- return emulation_bytes_count;
- }
- static u32 avc_add_emulation_bytes(const char *buffer_src, char *buffer_dst, u32 nal_size)
- {
- u32 i = 0, emulation_bytes_count = 0;
- u8 num_zero = 0;
- while (i < nal_size) {
- /*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003
- other than the following sequences shall not occur at any byte-aligned position:
- 0x00000300
- 0x00000301
- 0x00000302
- 0x00000303"
- */
- if (num_zero == 2 && buffer_src[i] < 0x04) {
- /*add emulation code*/
- num_zero = 0;
- buffer_dst[i+emulation_bytes_count] = 0x03;
- emulation_bytes_count++;
- if (!buffer_src[i])
- num_zero = 1;
- } else {
- if (!buffer_src[i])
- num_zero++;
- else
- num_zero = 0;
- }
- buffer_dst[i+emulation_bytes_count] = buffer_src[i];
- i++;
- }
- return nal_size+emulation_bytes_count;
- }
- #ifdef GPAC_UNUSED_FUNC
- /*returns the nal_size without emulation prevention bytes*/
- static u32 avc_emulation_bytes_remove_count(unsigned char *buffer, u32 nal_size)
- {
- u32 i = 0, emulation_bytes_count = 0;
- u8 num_zero = 0;
- while (i < nal_size)
- {
- /*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003
- other than the following sequences shall not occur at any byte-aligned position:
- \96 0x00000300
- \96 0x00000301
- \96 0x00000302
- \96 0x00000303"
- */
- if (num_zero == 2
- && buffer[i] == 0x03
- && i+1 < nal_size /*next byte is readable*/
- && buffer[i+1] < 0x04)
- {
- /*emulation code found*/
- num_zero = 0;
- emulation_bytes_count++;
- i++;
- }
- if (!buffer[i])
- num_zero++;
- else
- num_zero = 0;
- i++;
- }
- return emulation_bytes_count;
- }
- #endif /*GPAC_UNUSED_FUNC*/
- /*nal_size is updated to allow better error detection*/
- static u32 avc_remove_emulation_bytes(const char *buffer_src, char *buffer_dst, u32 nal_size)
- {
- u32 i = 0, emulation_bytes_count = 0;
- u8 num_zero = 0;
- while (i < nal_size)
- {
- /*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003
- other than the following sequences shall not occur at any byte-aligned position:
- 0x00000300
- 0x00000301
- 0x00000302
- 0x00000303"
- */
- if (num_zero == 2
- && buffer_src[i] == 0x03
- && i+1 < nal_size /*next byte is readable*/
- && buffer_src[i+1] < 0x04)
- {
- /*emulation code found*/
- num_zero = 0;
- emulation_bytes_count++;
- i++;
- }
- buffer_dst[i-emulation_bytes_count] = buffer_src[i];
- if (!buffer_src[i])
- num_zero++;
- else
- num_zero = 0;
- i++;
- }
- return nal_size-emulation_bytes_count;
- }
- GF_EXPORT
- s32 gf_media_avc_read_sps(const char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps, u32 *vui_flag_pos)
- {
- AVC_SPS *sps;
- u32 ChromaArrayType = 0;
- s32 mb_width, mb_height, sps_id = -1;
- u32 profile_idc, level_idc, pcomp, i, chroma_format_idc, cl, cr, ct, cb, luma_bd, chroma_bd;
- GF_BitStream *bs;
- char *sps_data_without_emulation_bytes = NULL;
- u32 sps_data_without_emulation_bytes_size = 0;
- /*SPS still contains emulation bytes*/
- sps_data_without_emulation_bytes = gf_malloc(sps_size*sizeof(char));
- sps_data_without_emulation_bytes_size = avc_remove_emulation_bytes(sps_data, sps_data_without_emulation_bytes, sps_size);
- bs = gf_bs_new(sps_data_without_emulation_bytes, sps_data_without_emulation_bytes_size, GF_BITSTREAM_READ);
- if (!bs) {
- sps_id = -1;
- goto exit;
- }
- if (vui_flag_pos) *vui_flag_pos = 0;
- /*nal hdr*/ gf_bs_read_int(bs, 8);
- profile_idc = gf_bs_read_int(bs, 8);
- pcomp = gf_bs_read_int(bs, 8);
- /*sanity checks*/
- if (pcomp & 0x3)
- goto exit;
- level_idc = gf_bs_read_int(bs, 8);
- /*SubsetSps is used to be sure that AVC SPS are not going to be scratched
- by subset SPS. According to the SVC standard, subset SPS can have the same sps_id
- than its base layer, but it does not refer to the same SPS. */
- sps_id = bs_get_ue(bs) + GF_SVC_SSPS_ID_SHIFT * subseq_sps;
- if (sps_id >=32) {
- sps_id = -1;
- goto exit;
- }
- chroma_format_idc = luma_bd = chroma_bd = 0;
- sps = &avc->sps[sps_id];
- sps->state |= subseq_sps ? AVC_SUBSPS_PARSED : AVC_SPS_PARSED;
- /*High Profile and SVC*/
- switch (profile_idc) {
- case 100:
- case 110:
- case 122:
- case 244:
- case 44:
- /*sanity checks: note1 from 7.4.2.1.1 of iso/iec 14496-10-N11084*/
- if (pcomp & 0xE0)
- goto exit;
- case 83:
- case 86:
- case 118:
- case 128:
- chroma_format_idc = bs_get_ue(bs);
- ChromaArrayType = chroma_format_idc;
- if (chroma_format_idc == 3) {
- u8 separate_colour_plane_flag = gf_bs_read_int(bs, 1);
- /*
- Depending on the value of separate_colour_plane_flag, the value of the variable ChromaArrayType is assigned as follows.
- \96 If separate_colour_plane_flag is equal to 0, ChromaArrayType is set equal to chroma_format_idc.
- \96 Otherwise (separate_colour_plane_flag is equal to 1), ChromaArrayType is set equal to 0.
- */
- if (separate_colour_plane_flag) ChromaArrayType = 0;
- }
- luma_bd = bs_get_ue(bs);
- chroma_bd = bs_get_ue(bs);
- /*qpprime_y_zero_transform_bypass_flag = */ gf_bs_read_int(bs, 1);
- /*seq_scaling_matrix_present_flag*/
- if (gf_bs_read_int(bs, 1)) {
- u32 k;
- for (k=0; k<8; k++) {
- if (gf_bs_read_int(bs, 1)) {
- u32 z, last = 8, next = 8;
- u32 sl = k<6 ? 16 : 64;
- for (z=0; z<sl; z++) {
- if (next) {
- s32 delta = bs_get_se(bs);
- next = (last + delta + 256) % 256;
- }
- last = next ? next : last;
- }
- }
- }
- }
- break;
- default :
- ChromaArrayType = chroma_format_idc = 1;
- break;
- }
- sps->profile_idc = profile_idc;
- sps->level_idc = level_idc;
- sps->prof_compat = pcomp;
- sps->log2_max_frame_num = bs_get_ue(bs) + 4;
- sps->poc_type = bs_get_ue(bs);
- sps->chroma_format = chroma_format_idc;
- sps->luma_bit_depth_m8 = luma_bd;
- sps->chroma_bit_depth_m8 = chroma_bd;
- if (sps->poc_type == 0) {
- sps->log2_max_poc_lsb = bs_get_ue(bs) + 4;
- } else if(sps->poc_type == 1) {
- sps->delta_pic_order_always_zero_flag = gf_bs_read_int(bs, 1);
- sps->offset_for_non_ref_pic = bs_get_se(bs);
- sps->offset_for_top_to_bottom_field = bs_get_se(bs);
- sps->poc_cycle_length = bs_get_ue(bs);
- for(i=0; i<sps->poc_cycle_length; i++) sps->offset_f…
Large files files are truncated, but you can click here to view the full file