2008-04-14 04:09:29 +00:00
|
|
|
|
/*
|
|
|
|
|
* Datastructures for manipulating NAL units in H.264 elementary streams.
|
|
|
|
|
*
|
|
|
|
|
* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
|
* Version: MPL 1.1
|
|
|
|
|
*
|
|
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
|
* http://www.mozilla.org/MPL/
|
|
|
|
|
*
|
|
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
|
* License.
|
|
|
|
|
*
|
|
|
|
|
* The Original Code is the MPEG TS, PS and ES tools.
|
|
|
|
|
*
|
|
|
|
|
* The Initial Developer of the Original Code is Amino Communications Ltd.
|
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2008
|
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s):
|
|
|
|
|
* Amino Communications Ltd, Swavesey, Cambridge UK
|
|
|
|
|
*
|
|
|
|
|
* ***** END LICENSE BLOCK *****
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef _nalunit_defns
|
|
|
|
|
#define _nalunit_defns
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include "compat.h"
|
|
|
|
|
#include "es_defns.h"
|
|
|
|
|
#include "bitdata_defns.h"
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
// Constants and definitions
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
enum NAL_UNIT_TYPE
|
|
|
|
|
{
|
|
|
|
|
NAL_UNSPECIFIED,
|
|
|
|
|
NAL_NON_IDR,
|
|
|
|
|
NAL_PARTITION_A,
|
|
|
|
|
NAL_PARTITION_B,
|
|
|
|
|
NAL_PARTITION_C,
|
|
|
|
|
NAL_IDR,
|
|
|
|
|
NAL_SEI,
|
|
|
|
|
NAL_SEQ_PARAM_SET,
|
|
|
|
|
NAL_PIC_PARAM_SET,
|
|
|
|
|
NAL_ACCESS_UNIT_DELIM,
|
|
|
|
|
NAL_END_OF_SEQ,
|
|
|
|
|
NAL_END_OF_STREAM,
|
|
|
|
|
NAL_FILLER
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define NAL_UNIT_TYPE_STR(a) \
|
|
|
|
|
((a)==NAL_UNSPECIFIED?"unspecified": \
|
|
|
|
|
(a)==NAL_NON_IDR?"non-IDR": \
|
|
|
|
|
(a)==NAL_PARTITION_A?"partition A": \
|
|
|
|
|
(a)==NAL_PARTITION_B?"partition B": \
|
|
|
|
|
(a)==NAL_PARTITION_C?"partition C": \
|
|
|
|
|
(a)==NAL_IDR?"IDR": \
|
|
|
|
|
(a)==NAL_SEI?"SEI": \
|
|
|
|
|
(a)==NAL_SEQ_PARAM_SET?"seq param set": \
|
|
|
|
|
(a)==NAL_PIC_PARAM_SET?"pic param set": \
|
|
|
|
|
(a)==NAL_ACCESS_UNIT_DELIM?"access unit delim": \
|
|
|
|
|
(a)==NAL_END_OF_SEQ?"end of seq": \
|
|
|
|
|
(a)==NAL_END_OF_STREAM?"end of stream": \
|
|
|
|
|
(a)==NAL_FILLER?"filler":"???")
|
|
|
|
|
|
|
|
|
|
#define SLICE_P 0
|
|
|
|
|
#define SLICE_B 1
|
|
|
|
|
#define SLICE_I 2
|
|
|
|
|
#define SLICE_SP 3
|
|
|
|
|
#define SLICE_SI 4
|
|
|
|
|
#define ALL_SLICES_P 5
|
|
|
|
|
#define ALL_SLICES_B 6
|
|
|
|
|
#define ALL_SLICES_I 7
|
|
|
|
|
#define ALL_SLICES_SP 8
|
|
|
|
|
#define ALL_SLICES_SI 9
|
|
|
|
|
|
2008-04-29 12:26:17 +00:00
|
|
|
|
#define NAL_SLICE_TYPE_STR(a) \
|
|
|
|
|
((a)==SLICE_P?"First P": (a)==SLICE_B?"First B": (a)==SLICE_I?"First I": \
|
|
|
|
|
(a)==SLICE_SP?"First SP": (a)==SLICE_SI?"First SI": \
|
|
|
|
|
(a)==ALL_SLICES_P?"All P": (a)==ALL_SLICES_B?"All B": \
|
|
|
|
|
(a)==ALL_SLICES_I?"All I": (a)==ALL_SLICES_SP?"All SP": \
|
|
|
|
|
(a)==ALL_SLICES_SI?"All SI":"??")
|
2008-04-14 04:09:29 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
// Datastructures
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
// Data for a slice NAL unit
|
|
|
|
|
struct nal_slice_data
|
|
|
|
|
{
|
|
|
|
|
u_int32 seq_param_set_pic_order_cnt_type; // from the seq param set
|
|
|
|
|
u_int32 first_mb_in_slice;
|
|
|
|
|
u_int32 slice_type;
|
|
|
|
|
u_int32 pic_parameter_set_id;
|
|
|
|
|
u_int32 frame_num;
|
|
|
|
|
// From here onwards, the fields are not necessarily all present
|
|
|
|
|
byte field_pic_flag; // frame or field? 0 if absent
|
|
|
|
|
byte bottom_field_flag; // 0 if absent
|
|
|
|
|
int bottom_field_flag_present;
|
|
|
|
|
u_int32 idr_pic_id;
|
|
|
|
|
u_int32 pic_order_cnt_lsb;
|
|
|
|
|
int32 delta_pic_order_cnt_bottom;
|
|
|
|
|
int32 delta_pic_order_cnt[2];
|
|
|
|
|
u_int32 redundant_pic_cnt;
|
|
|
|
|
int redundant_pic_cnt_present;
|
|
|
|
|
};
|
|
|
|
|
typedef struct nal_slice_data *nal_slice_data_p;
|
|
|
|
|
#define SIZEOF_NAL_SLICE_DATA sizeof(struct nal_slice_data)
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
// Data for a sequence parameter set
|
|
|
|
|
struct nal_seq_param_data
|
|
|
|
|
{
|
|
|
|
|
byte profile_idc;
|
|
|
|
|
byte constraint_set0_flag;
|
|
|
|
|
byte constraint_set1_flag;
|
|
|
|
|
byte constraint_set2_flag;
|
|
|
|
|
byte level_idc;
|
|
|
|
|
u_int32 seq_parameter_set_id; // our own id (0..31)
|
|
|
|
|
u_int32 log2_max_frame_num;
|
|
|
|
|
u_int32 pic_order_cnt_type;
|
|
|
|
|
u_int32 log2_max_pic_order_cnt_lsb;
|
|
|
|
|
byte delta_pic_order_always_zero_flag;
|
|
|
|
|
byte frame_mbs_only_flag;
|
|
|
|
|
};
|
|
|
|
|
typedef struct nal_seq_param_data *nal_seq_param_data_p;
|
|
|
|
|
#define SIZEOF_NAL_SEQ_PARAM_DATA sizeof(struct nal_seq_param_data)
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
// Data for a picture parameter set
|
|
|
|
|
struct nal_pic_param_data
|
|
|
|
|
{
|
|
|
|
|
int pic_parameter_set_id; // our own id (0..255)
|
|
|
|
|
int seq_parameter_set_id; // we use this
|
|
|
|
|
byte entropy_coding_mode_flag;
|
|
|
|
|
byte pic_order_present_flag; // we use this
|
|
|
|
|
u_int32 num_slice_groups;
|
|
|
|
|
u_int32 slice_group_map_type;
|
|
|
|
|
// lots of ignored things
|
|
|
|
|
byte redundant_pic_cnt_present_flag; // this is mildly interesting
|
|
|
|
|
};
|
|
|
|
|
typedef struct nal_pic_param_data *nal_pic_param_data_p;
|
|
|
|
|
#define SIZEOF_NAL_PIC_PARAM_DATA sizeof(struct nal_pic_param_data)
|
|
|
|
|
|
2008-05-22 14:19:02 +00:00
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
// Data for a Supplemental enhancement information (SEI) nal unit
|
|
|
|
|
struct nal_SEI_recovery_data
|
|
|
|
|
{
|
|
|
|
|
int payloadType; // type of SEI unit
|
|
|
|
|
int payloadSize; // in byte
|
|
|
|
|
|
|
|
|
|
int recovery_frame_cnt;
|
|
|
|
|
byte exact_match_flag;
|
|
|
|
|
byte broken_link_flag;
|
|
|
|
|
u_int32 changing_slice_group_idc;
|
|
|
|
|
};
|
|
|
|
|
typedef struct nal_SEI_recovery_data *nal_SEI_recovery_data_p;
|
|
|
|
|
#define SIZEOF_NAL_SEI_RECOVERY_DATA sizeof(struct nal_SEI_recovery_data)
|
|
|
|
|
|
2008-04-14 04:09:29 +00:00
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
// An individual NAL unit might hold any one of those...
|
|
|
|
|
union nal_innards
|
|
|
|
|
{
|
2008-05-22 14:19:02 +00:00
|
|
|
|
struct nal_slice_data slice;
|
|
|
|
|
struct nal_seq_param_data seq;
|
|
|
|
|
struct nal_pic_param_data pic;
|
|
|
|
|
struct nal_SEI_recovery_data sei_recovery;
|
2008-04-14 04:09:29 +00:00
|
|
|
|
};
|
|
|
|
|
typedef union nal_innards *nal_innards_p;
|
|
|
|
|
#define SIZEOF_NAL_INNARDS sizeof(union nal_innards)
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
// "Dictionaries" for finding a specific picture parameter set or
|
|
|
|
|
// sequence parameter set
|
|
|
|
|
// Picture parameter set ids are in the range 0..255
|
|
|
|
|
// Sequence parameter set ids are in the range 0..31
|
|
|
|
|
struct param_dict
|
|
|
|
|
{
|
|
|
|
|
int last_id; // The id of the last parameter set we wanted
|
|
|
|
|
int last_index; // and its index in the arrays
|
2008-05-22 14:19:02 +00:00
|
|
|
|
int *ids; // The ids for...
|
2008-04-14 04:09:29 +00:00
|
|
|
|
union nal_innards *params; // ...the data
|
|
|
|
|
ES_offset *posns; // Where each was read from...
|
|
|
|
|
u_int32 *data_lens; // ...and its size
|
|
|
|
|
int size, length; // of the arrays and their content
|
|
|
|
|
};
|
|
|
|
|
typedef struct param_dict *param_dict_p;
|
|
|
|
|
#define SIZEOF_PARAM_DICT sizeof(struct param_dict)
|
|
|
|
|
|
|
|
|
|
#define NAL_PIC_PARAM_START_SIZE 20
|
|
|
|
|
#define NAL_PIC_PARAM_INCREMENT 20
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
// A single NAL unit
|
|
|
|
|
struct nal_unit
|
|
|
|
|
{
|
|
|
|
|
struct ES_unit unit; // The actual data
|
|
|
|
|
|
|
|
|
|
// For most purposes, it's simplest to think about the NAL unit's data as
|
|
|
|
|
// being the data *after* the start code prefix. Indeed, that is the way
|
|
|
|
|
// that it is presented in the standard. Thus we provide aliases here, which
|
|
|
|
|
// do so
|
|
|
|
|
// (NB: since these point "into" the .unit structure, they will only be
|
|
|
|
|
// meaningful after we've finished reading in a NAL unit's data - before
|
|
|
|
|
// then they're undefined)
|
|
|
|
|
byte *data; // The current NAL unit's data, excluding 00 00 01
|
|
|
|
|
int data_len; // And its length/size
|
|
|
|
|
|
|
|
|
|
// And for some processing, we need to work with the data after
|
|
|
|
|
// it has had its emulation 3 bytes removed
|
|
|
|
|
byte *rbsp; // The data with 00 00 03 bytes "fixed"
|
|
|
|
|
int rbsp_len;
|
|
|
|
|
bitdata_p bit_data; // And a view of that as bits
|
|
|
|
|
|
|
|
|
|
// Information obtained by inspection of the NAL units content
|
|
|
|
|
int nal_ref_idc;
|
|
|
|
|
enum NAL_UNIT_TYPE nal_unit_type;
|
|
|
|
|
int starts_picture_decided;
|
|
|
|
|
int starts_picture;
|
|
|
|
|
char *start_reason; // If it starts a picture, why
|
|
|
|
|
|
|
|
|
|
int decoded; // Have we "read" the innards of the NAL unit?
|
2008-05-22 14:19:02 +00:00
|
|
|
|
union nal_innards u; // Admittedly an unimaginative name, but short
|
2008-04-14 04:09:29 +00:00
|
|
|
|
};
|
|
|
|
|
typedef struct nal_unit *nal_unit_p;
|
|
|
|
|
#define SIZEOF_NAL_UNIT sizeof(struct nal_unit)
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
// An expandable list of NAL units
|
|
|
|
|
struct nal_unit_list
|
|
|
|
|
{
|
|
|
|
|
nal_unit_p *array; // The current array of nal units */
|
|
|
|
|
int length; // How many there are
|
|
|
|
|
int size; // How big the array is
|
|
|
|
|
};
|
|
|
|
|
typedef struct nal_unit_list *nal_unit_list_p;
|
|
|
|
|
#define SIZEOF_NAL_UNIT_LIST sizeof(struct nal_unit_list)
|
|
|
|
|
|
|
|
|
|
#define NAL_UNIT_LIST_START_SIZE 20
|
|
|
|
|
#define NAL_UNIT_LIST_INCREMENT 20
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
// A context for reading NAL units from an Elementary Stream
|
|
|
|
|
struct nal_unit_context
|
|
|
|
|
{
|
|
|
|
|
ES_p es;
|
|
|
|
|
int count;
|
|
|
|
|
// Sequence and picture parameter set "dictionaries"
|
|
|
|
|
param_dict_p seq_param_dict;
|
|
|
|
|
param_dict_p pic_param_dict;
|
|
|
|
|
|
|
|
|
|
// Show details of each NAL units content as it is read?
|
|
|
|
|
int show_nal_details;
|
|
|
|
|
};
|
|
|
|
|
typedef struct nal_unit_context *nal_unit_context_p;
|
|
|
|
|
#define SIZEOF_NAL_UNIT_CONTEXT sizeof(struct nal_unit_context)
|
|
|
|
|
|
|
|
|
|
#endif // _nalunit_defns
|
2008-06-14 16:05:00 +00:00
|
|
|
|
|
|
|
|
|
// Local Variables:
|
|
|
|
|
// tab-width: 8
|
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
|
// c-basic-offset: 2
|
|
|
|
|
// End:
|
|
|
|
|
// vim: set tabstop=8 shiftwidth=2 expandtab:
|