/* * 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 #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: