F5OEO-tstools/h262_defns.h

256 wiersze
11 KiB
C
Czysty Zwykły widok Historia

/*
* Datastructures for reading H.262 (MPEG-2) 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 _h262_defns
#define _h262_defns
#include <stdio.h>
#include "compat.h"
#include "es_defns.h"
#include "ts_defns.h"
// Since reverse_data refers to h262 and acces_unit datastructures, and
// *they* refer to reverse_data, we need to break the circular referencing
// at some point
typedef struct h262_context *h262_context_p;
struct reverse_data;
// ------------------------------------------------------------
// An MPEG "item", the set of bytes that starts with a start code prefix.
struct _h262_item
{
struct ES_unit unit; // The actual data
// MPEG2 specific data
byte picture_coding_type; // only defined if unit.start_code == 0
};
typedef struct _h262_item *h262_item_p;
#define SIZEOF_H262_ITEM sizeof(struct _h262_item)
// ------------------------------------------------------------
// An H.262 "picture". This might be a picture or a sequence header (and
// its associated items).
struct _h262_picture
{
// The main thing we need is a list of the items that make up this picture
ES_unit_list_p list;
// An H.262 "picture" might be a "proper" picture, a sequence header,
// or (just) a sequence end item. It's useful to be able to identify
// the two more common cases easily
int is_picture;
int is_sequence_header;
// Data defined for a picture. When a picture is composed of the data
// from two fields, then these will be the values taken from the first
// field "picture".
byte picture_coding_type; // I, P or B
byte picture_structure; // top/bottom field or frame
uint16_t temporal_reference; // presentation order within a group
byte afd; // its "Active Format Description" value
// (NB: with 0xF0 bits set at top of byte)
byte is_real_afd; // was it a *real* AFD?
int was_two_fields; // TRUE if it's a frame merged from two fields
// Data defined for a sequence header/extension
// Note that H.262 requires that data given in one sequence extension
// shall be the same as that in all the others in the stream. Thus, in
// particular, we know that if fields are allowed by one sequence
// extension, they will be allowed by all.
byte progressive_sequence; // frames or frames and fields allowed?
// Data defined for both
// (in a frame, this is the value from the previous section header)
byte aspect_ratio_info; // its aspect ratio code
};
typedef struct _h262_picture *h262_picture_p;
#define SIZEOF_H262_PICTURE sizeof(struct _h262_picture)
// ------------------------------------------------------------
// Produce a nice string for the start code. `b` must be a byte.
#define H262_START_CODE_STR(b) \
((b)==0x00?"picture": \
(b)>=0x01 && b<=0xAF?"slice": \
(b)==0xB0?"reserved": \
(b)==0xB1?"reserved": \
(b)==0xB2?"user data": \
(b)==0xB3?"sequence header": \
(b)==0xB4?"sequence error": \
(b)==0xB5?"extension start": \
(b)==0xB6?"reserved": \
(b)==0xB7?"sequence end": \
(b)==0xB8?"group start": \
(b)>=0xB9?"system start":"???")
#define is_h262_picture_item(item) ((item)->unit.start_code==0x00)
#define is_h262_slice_item(item) ((item)->unit.start_code>=0x01 && \
(item)->unit.start_code<=0xAF)
#define is_h262_user_data_item(item) ((item)->unit.start_code==0xB2)
#define is_h262_seq_header_item(item) ((item)->unit.start_code==0xB3)
#define is_h262_seq_end_item(item) ((item)->unit.start_code==0xB7)
#define is_h262_group_start_item(item) ((item)->unit.start_code==0xB8)
#define is_h262_extension_start_item(item) ((item)->unit.start_code==0xB5)
#define H262_PICTURE_CODING_STR(s) \
((s)==0?"Forbidden": \
(s)==1?"I": \
(s)==2?"P": \
(s)==3?"B": \
(s)==4?"D":"Reserved")
// The following two macros can be used on H.262 items *or* pictures
#define is_I_picture(picture) ((picture)->picture_coding_type==1)
#define is_P_picture(picture) ((picture)->picture_coding_type==2)
#define H262_PICTURE_STRUCTURE_STR(s) \
((s)==0?"Reserved": \
(s)==1?"Top Field": \
(s)==2?"Bottom Field": \
(s)==3?"Frame":"???")
#define is_h262_field_picture(picture) ((picture)->is_picture && \
((picture)->picture_structure == 1 ||\
(picture)->picture_structure == 2))
#define is_h262_AFD_user_data_item(item) \
((item)->unit.start_code == 0xB2 && \
(item)->unit.data_len > 8 && \
(item)->unit.data[4] == 0x44 && \
(item)->unit.data[5] == 0x54 && \
(item)->unit.data[6] == 0x47 && \
(item)->unit.data[7] == 0x31)
#define UNSET_AFD_BYTE 0xF8 // i.e., '1111 1000'
// String values taken from ATSC Digital Television Standard, Rev C,
// (A/53C) 12 May 2004, which will hopefully be correct for DVB as well...
#define AFD_STR(afd) \
((afd)==0xF2?"ATSC: box 16:9 (top)": \
(afd)==0xF3?"ATSC: box 14:9 (top)": \
(afd)==0xF4?"ATSC: box > 16:9 (center)": \
(afd)==0xF8?"Active format as coded frame": \
(afd)==0xF9?"4:3 (centre)": \
(afd)==0xFA?"16:9 (centre)": \
(afd)==0xFB?"14:9 (centre)": \
(afd)==0xFC?"reserved": \
(afd)==0xFD?"4:3 (with shoot & protect 14:9 centre)": \
(afd)==0xFE?"16:9 (with shoot & protect 14:9 centre)": \
(afd)==0xFF?"16:9 (with shoot & protect 4:3 centre)":"reserved")
#define SHORT_AFD_STR(afd) \
((afd)==0xF2?"ATSC: box 16:9 (top)": \
(afd)==0xF3?"ATSC: box 14:9 (top)": \
(afd)==0xF4?"ATSC: box > 16:9 (center)": \
(afd)==0xF8?"As coded frame": \
(afd)==0xF9?"4:3 (centre)": \
(afd)==0xFA?"16:9 (centre)": \
(afd)==0xFB?"14:9 (centre)": \
(afd)==0xFC?"reserved": \
(afd)==0xFD?"4:3 (14:9)": \
(afd)==0xFE?"16:9 (14:9)": \
(afd)==0xFF?"16:9 (4:3)":"reserved")
// The standard does not define value FF, so I'm choosing it as an "unset"
// value, so that I get sensible diagnostics when a picture is reported
// on before a section header has been read
#define H262_UNSET_ASPECT_RATIO_INFO 0xFF
#define H262_ASPECT_RATIO_INFO_STR(rat) ((rat)==0xFF?"Unset": \
(rat)==0?"Forbidden aspect ratio": \
(rat)==1?"Square": \
(rat)==2?"4:3": \
(rat)==3?"16:9": \
"Reserved aspect ratio")
// ------------------------------------------------------------
// Context for looping over the H.262 items and pictures in an elementary
// stream
struct h262_context
{
ES_p es;
// We count all of the pictures as we read them (this is useful
// when we are building up reverse_data arrays). If functions
// move around in the data stream, we assume that they will
// (re)set this to a sensible value.
// The index of the first picture read is 1, and this value is
// incremented by each call of `get_next_h262_picture` (note that
// for this purpose, sequence headers are *not* considered pictures)
uint32_t picture_index; // The index of the last picture read
// We detect the end of an H.262 picture (or sequence header) by
// reading the first item that cannot be part of it. We then need
// to remember that item for *next* time we try to read a picture.
h262_item_p last_item;
// What was the aspect ratio code from the last sequence header?
byte last_aspect_ratio_info;
// When we are reading MPEG-2, we may encounter AFD (Active Format
// Definiton) user data. This sets the aspect ratio of the following
// picture(s), possibly overriding information present in a preceding
// sequence header. It should only be present for I pictures, really,
// but we remember it for all pictures.
// Once an AFD value has been set, it stands until another value is read.
// This all becomes important when reversing, which see.
// Anyway, in order to set the AFD on pictures which don't have it
// explicitly, we obviously need to remember the last value found.
// For simplicity of use, we remember the whole byte it came in,
// including the 0xF0 reserved bits at the top of the byte.
// Note that '1000' (8) is the "unset" value.
byte last_afd;
// When we are reading an H.262 picture back in, for reversing purposes, or
// reading frames for filtering, it is useful to *insist* that an AFD be
// found for the picture. Thus, if `add_fake_afd` is TRUE, a dummy AFD,
// containing the value in `last_afd`, will be inserted into the picture's
// ES unit `list` (of course, if the picture contains a *real* AFD, this is
// not necessary). Beware that the ES unit inserted won't stand up to close
// observation, as its start position (for instance) will clearly be
// wrong...
// (this is manipulated by the reversing and filtering code - it is not
// intended for use for any other purpose)
int add_fake_afd;
// If we are collecting reversing information, then we keep a reference
// to the reverse data here
struct reverse_data * reverse_data;
// In the same context, we need to remember how long it is since the
// last sequence header
byte count_since_seq_hdr;
};
#define SIZEOF_H262_CONTEXT sizeof(struct h262_context)
#endif // _h262_defns
// Local Variables:
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 2
// End:
// vim: set tabstop=8 shiftwidth=2 expandtab: