kopia lustrzana https://github.com/F5OEO/tstools
272 wiersze
9.3 KiB
C
272 wiersze
9.3 KiB
C
/*
|
||
* 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
|
||
|
||
#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":"??")
|
||
|
||
|
||
// ------------------------------------------------------------
|
||
// Datastructures
|
||
// ------------------------------------------------------------
|
||
// Data for a slice NAL unit
|
||
struct nal_slice_data
|
||
{
|
||
uint32_t seq_param_set_pic_order_cnt_type; // from the seq param set
|
||
uint32_t first_mb_in_slice;
|
||
uint32_t slice_type;
|
||
uint32_t pic_parameter_set_id;
|
||
uint32_t 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;
|
||
uint32_t idr_pic_id;
|
||
uint32_t pic_order_cnt_lsb;
|
||
int32_t delta_pic_order_cnt_bottom;
|
||
int32_t delta_pic_order_cnt[2];
|
||
uint32_t 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;
|
||
uint32_t seq_parameter_set_id; // our own id (0..31)
|
||
uint32_t log2_max_frame_num;
|
||
uint32_t pic_order_cnt_type;
|
||
uint32_t 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
|
||
uint32_t num_slice_groups;
|
||
uint32_t 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)
|
||
|
||
// ------------------------------------------------------------
|
||
// 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;
|
||
uint32_t 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)
|
||
|
||
// ------------------------------------------------------------
|
||
// An individual NAL unit might hold any one of those...
|
||
union nal_innards
|
||
{
|
||
struct nal_slice_data slice;
|
||
struct nal_seq_param_data seq;
|
||
struct nal_pic_param_data pic;
|
||
struct nal_SEI_recovery_data sei_recovery;
|
||
};
|
||
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
|
||
int *ids; // The ids for...
|
||
union nal_innards *params; // ...the data
|
||
ES_offset *posns; // Where each was read from...
|
||
uint32_t *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?
|
||
union nal_innards u; // Admittedly an unimaginative name, but short
|
||
};
|
||
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
|
||
|
||
// Local Variables:
|
||
// tab-width: 8
|
||
// indent-tabs-mode: nil
|
||
// c-basic-offset: 2
|
||
// End:
|
||
// vim: set tabstop=8 shiftwidth=2 expandtab:
|