/* * Support for ISO/IEC 14496-3:2001(E) AAC ADTS audio 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 ***** */ #include #include #include #include #include "compat.h" #include "misc_fns.h" #include "adts_fns.h" #define DEBUG 0 /* * Read the next ADTS frame. * * Assumes that the input stream is synchronised - i.e., it does not * try to cope if the next three bytes are not '1111 1111 1111'. * * - `file` is the file descriptor of the ADTS file to read from * - `frame` is the ADTS frame that is read * * Returns 0 if all goes well, EOF if end-of-file is read, and 1 if something * goes wrong. */ extern int read_next_adts_frame(int file, audio_frame_p *frame) { #define JUST_ENOUGH 6 // just enough to hold the bits of the headers we want int err, ii; int id, layer; byte header[JUST_ENOUGH]; byte *data = NULL; int frame_length; offset_t posn = tell_file(file); #if DEBUG printf("Offset: " OFFSET_T_FORMAT "\n",posn); #endif err = read_bytes(file,JUST_ENOUGH,header); if (err == EOF) return EOF; else if (err) { fprintf(stderr,"### Error reading header bytes of ADTS frame\n"); fprintf(stderr," (in frame starting at " OFFSET_T_FORMAT ")\n",posn); free(data); return 1; } #if DEBUG printf("ADTS frame\n"); print_data(stdout,"Start",header,JUST_ENOUGH,JUST_ENOUGH); #endif if (header[0] != 0xFF || (header[1] & 0xF0) != 0xF0) { fprintf(stderr,"### ADTS frame does not start with '1111 1111 1111'" " syncword - lost synchronisation?\n" " Found 0x%X%X%X instead of 0xFFF\n", (unsigned)(header[0] & 0xF0) >> 4, (header[0] & 0x0F), (unsigned)(header[1] & 0xF0) >> 4); fprintf(stderr," (in frame starting at " OFFSET_T_FORMAT ")\n",posn); return 1; } id = (header[1] & 0x08) >> 3; #if DEBUG printf(" ID %d (%s)\n",id,(id==1?"MPEG-2 AAC":"MPEG-4")); #endif layer = (header[1] & 0x06) >> 1; if (layer != 0) printf(" layer is %d, not 0 (in frame at " OFFSET_T_FORMAT ")\n", layer,posn); if (id == 1) { // We assume the Emphasis field is not present // (experience appears to show that it is not used for MPEG-2 AVC) frame_length = ((header[3] & 0x03) << 11) | (header[4] << 3) | ((unsigned)(header[5] & 0xE0) >> 5); } else { // We assume the Emphasis field *is* present frame_length = (header[4] << 5) | ((unsigned)(header[5] & 0xF8) >> 3); } #if DEBUG printf(" length %d\n",frame_length); #endif data = malloc(frame_length); if (data == NULL) { fprintf(stderr,"### Unable to extend data buffer for ADTS frame\n"); free(data); return 1; } for (ii=0; iidata = data; (*frame)->data_len = frame_length; return 0; } // Local Variables: // tab-width: 8 // indent-tabs-mode: nil // c-basic-offset: 2 // End: // vim: set tabstop=8 shiftwidth=2 expandtab: