Add AC3 support to esmerge.

--HG--
extra : convert_revision : svn%3Aeff31bef-be4a-0410-a8fe-e47997df2690/trunk%4061
issue20
rhodri 2008-09-09 13:45:11 +00:00
rodzic 9f0b83b97b
commit 2b3fb08215
7 zmienionych plików z 268 dodań i 3 usunięć

Wyświetl plik

@ -90,6 +90,7 @@ BINDIR = bin
# All of our non-program source files
SRCS = \
accessunit.c \
ac3.c \
adts.c \
avs.c \
bitdata.c \
@ -111,6 +112,7 @@ SRCS = \
OBJS = \
accessunit.o \
avs.o \
ac3.o \
adts.o \
bitdata.o \
es.o \
@ -149,6 +151,7 @@ PROG_OBJS = \
$(OBJDIR)/tsreport.o \
$(OBJDIR)/tsserve.o \
$(OBJDIR)/ts_packet_insert.o \
$(OBJDIR)/m2ts2ts.o
$(OBJDIR)/pcapreport.o
#\
# $(OBJDIR)/test_ps.o
@ -183,6 +186,7 @@ PROGS = \
$(BINDIR)/tsplay \
$(BINDIR)/tsserve \
$(BINDIR)/ts_packet_insert \
$(BINDIR)/m2ts2ts
$(BINDIR)/pcapreport
#\
# $(BINDIR)/test_ps
@ -266,6 +270,8 @@ $(BINDIR)/ts2ps: $(OBJDIR)/ts2ps.o $(LIB)
$(BINDIR)/ts_packet_insert: $(OBJDIR)/ts_packet_insert.o $(LIB)
$(CC) $< -o $(BINDIR)/ts_packet_insert $(LDFLAGS) $(LIBOPTS)
$(BINDIR)/m2ts2ts: $(OBJDIR)/m2ts2ts.o $(LIB)
$(CC) $< -o $(BINDIR)/m2ts2ts $(LDFLAGS) $(LIBOPTS)
$(BINDIR)/pcapreport: $(OBJDIR)/pcapreport.o $(LIB)
$(CC) $< -o $(BINDIR)/pcapreport $(LDFLAGS) $(LIBOPTS)
@ -295,7 +301,7 @@ H262_H = h262_fns.h h262_defns.h
TSWRITE_H = tswrite_fns.h tswrite_defns.h
REVERSE_H = reverse_fns.h reverse_defns.h
FILTER_H = filter_fns.h filter_defns.h $(REVERSE_H)
AUDIO_H = adts_fns.h l2audio_fns.h audio_fns.h audio_defns.h adts_defns.h
AUDIO_H = adts_fns.h l2audio_fns.h ac3_fns.h audio_fns.h audio_defns.h adts_defns.h
# Everyone depends upon the basic configuration file
$(LIB)($(OBJS)) $(TEST_OBJS) $(PROG_OBJS): compat.h
@ -344,6 +350,8 @@ $(OBJDIR)/tsplay.o: tsplay.c $(TS_H) misc_fns.h $(PS_H) $(PES_H) version.h
$(CC) -c $< -o $@ $(CFLAGS)
$(OBJDIR)/tswrite.o: tswrite.c misc_fns.h version.h
$(CC) -c $< -o $@ $(CFLAGS)
$(OBJDIR)/m2ts2ts.o: m2ts2ts.c $(TS_H) misc_fns.h version.h
$(CC) -c $< -o $@ $(CFLAGS)
$(OBJDIR)/pcapreport.o: pcapreport.c pcap.h version.h misc_fns.h
$(CC) -c $< -o $@ $(CFLAGS)

Wyświetl plik

@ -74,6 +74,7 @@ PROGS = \
$(EXEDIR)\ts2es.exe \
$(EXEDIR)\es2ts.exe \
$(EXEDIR)\esreverse.exe \
$(EXEDIR)\m2ts2ts.exe \
$(EXEDIR)\ps2ts.exe \
$(EXEDIR)\psreport.exe \
$(EXEDIR)\stream_type.exe \
@ -85,6 +86,7 @@ PROGS = \
# Object files for the library
LIB_OBJS = \
$(OBJDIR)\accessunit.obj \
$(OBJDIR)\ac3.obj \
$(OBJDIR)\adts.obj \
$(OBJDIR)\avs.obj \
$(OBJDIR)\audio.obj \
@ -111,6 +113,7 @@ PROG_OBJS = \
$(OBJDIR)/esmerge.obj \
$(OBJDIR)/esreport.obj \
$(OBJDIR)/esreverse.obj \
$(OBJDIR)/m2ts2ts.obj \
$(OBJDIR)/ps2ts.obj \
$(OBJDIR)/psreport.obj \
$(OBJDIR)/stream_type.obj \
@ -153,6 +156,9 @@ $(EXEDIR)\esreport.exe: $(OBJDIR)\esreport.obj $(LIBFILE)
$(EXEDIR)\esreverse.exe: $(OBJDIR)\esreverse.obj $(LIBFILE)
link /out:$@ $(LOPT) $** wsock32.lib
$(EXEDIR)\m2ts2ts.exe: $(OBJDIR)\m2ts2ts.obj $(LIBFILE)
link /out:$@ $(LOPT) $** wsock32.lib
$(EXEDIR)\stream_type.exe: $(OBJDIR)\stream_type.obj $(LIBFILE)
link /out:$@ $(LOPT) $** wsock32.lib

171
ac3.c 100644
Wyświetl plik

@ -0,0 +1,171 @@
/*
* Support for ATSC Digital Audio Compression Standard, Revision B
* (AC3) 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):
* Kynesim Ltd, Cambridge UK
*
* ***** END LICENSE BLOCK *****
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "compat.h"
#include "misc_fns.h"
#include "ac3_fns.h"
static const unsigned int // Table 5.18, frame sizes
l_frmsizecod[19][3] = {
{ 64, 69, 96 },
{ 80, 87, 120 },
{ 96, 104, 144 },
{ 112, 121, 168 },
{ 128, 139, 192 },
{ 160, 174, 240 },
{ 192, 208, 288 },
{ 224, 243, 336 },
{ 256, 278, 384 },
{ 320, 348, 480 },
{ 384, 417, 576 },
{ 448, 487, 672 },
{ 512, 557, 768 },
{ 640, 696, 960 },
{ 768, 835, 1152 },
{ 896, 975, 1344 },
{ 1024, 1114, 1536 },
{ 1152, 1253, 1728 },
{ 1280, 1393, 1920 }
};
/*
* Read the next AC3 frame.
*
* Assumes that the input stream is synchronised - i.e., it does not
* try to cope if the next two bytes are not '0000 1011 0111 0111'
*
* - `file` is the file descriptor of the AC3 file to read from
* - `frame` is the AC3 frame that is read
*
* Returns 0 if all goes well, EOF if end-of-file is read, and 1 if something
* goes wrong.
*/
#define SYNCINFO_SIZE 5
int read_next_ac3_frame(int file,
audio_frame_p *frame)
{
int i, err;
byte sync_info[SYNCINFO_SIZE];
byte *data = NULL;
int fscod;
int frmsizecod;
int frame_length;
offset_t posn = tell_file(file);
err = read_bytes(file, SYNCINFO_SIZE, sync_info);
if (err == EOF)
return EOF;
else if (err)
{
fprintf(stderr, "### Error reading syncinfo from AC3 file\n");
fprintf(stderr, " (in frame starting at " OFFSET_T_FORMAT ")\n", posn);
return 1;
}
if (sync_info[0] != 0x0b || sync_info[1] != 0x77)
{
fprintf(stderr, "### AC3 frame does not start with 0x0b77"
" syncword - lost synchronisation?\n"
" Found 0x%02x%02x instead of 0x0b77\n",
(unsigned)sync_info[0], (unsigned)sync_info[1]);
fprintf(stderr, " (in frame starting at " OFFSET_T_FORMAT ")\n", posn);
return 1;
}
fscod = sync_info[4] >> 6;
if (fscod == 3)
{
// Bad sample rate code
fprintf(stderr, "### Bad sample rate code in AC3 syncinfo\n");
fprintf(stderr, " (in frame starting at " OFFSET_T_FORMAT ")\n", posn);
return 1;
}
frmsizecod = sync_info[4] & 0x3f;
if (frmsizecod > 37)
{
fprintf(stderr, "### Bad frame size code %d in AC3 syncinfo\n",
frmsizecod);
fprintf(stderr, " (in frame starting at " OFFSET_T_FORMAT ")\n", posn);
return 1;
}
frame_length = l_frmsizecod[frmsizecod >> 1][fscod];
if (fscod == 1)
frame_length += frmsizecod & 1;
frame_length <<= 1; // Convert from 16-bit words to bytes
data = malloc(frame_length);
if (data == NULL)
{
fprintf(stderr, "### Unable to extend data buffer for AC3 frame\n");
return 1;
}
for (i = 0; i < SYNCINFO_SIZE; i++)
data[i] = sync_info[i];
err = read_bytes(file, frame_length - SYNCINFO_SIZE,
&data[SYNCINFO_SIZE]);
if (err)
{
if (err = EOF)
fprintf(stderr, "### Unexpected EOF reading rest of AC3 frame\n");
else
fprintf(stderr, "### Error reading rest of AC3 frame\n");
free(data);
return 1;
}
err = build_audio_frame(frame);
if (err)
{
free(data);
return 1;
}
(*frame)->data = 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:

59
ac3_fns.h 100644
Wyświetl plik

@ -0,0 +1,59 @@
/*
* Support for ATSC Digital Audio Compression Standard, Revision B
* (AC3) 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):
* Kynesim Ltd, Cambridge UK
*
* ***** END LICENSE BLOCK *****
*/
#ifndef _ac3_fns
#define _ac3_fns
#include "audio_fns.h"
/*
* Read the next AC3 frame.
*
* Assumes that the input stream is synchronised - i.e., it does not
* try to cope if the next two bytes are not '0000 1011 0111 0111'
*
* - `file` is the file descriptor of the AC3 file to read from
* - `frame` is the AC3 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_ac3_frame(int file,
audio_frame_p *frame);
#endif // _ac3_fns
// Local Variables:
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 2
// End:
// vim: set tabstop=8 shiftwidth=2 expandtab:

Wyświetl plik

@ -35,6 +35,7 @@
#include "audio_fns.h"
#include "adts_fns.h"
#include "l2audio_fns.h"
#include "ac3_fns.h"
/*
* Build a new generic audio frame datastructure
@ -106,6 +107,8 @@ extern int read_next_audio_frame(int file,
return read_next_adts_frame(file,frame,0);
case AUDIO_L2:
return read_next_l2audio_frame(file,frame);
case AUDIO_AC3:
return read_next_ac3_frame(file, frame);
default:
fprintf(stderr,"### Unrecognised audio type %d - cannot get next audio frame\n",
audio_type);

Wyświetl plik

@ -45,6 +45,7 @@ typedef struct audio_frame *audio_frame_p;
#define AUDIO_UNKNOWN 0 // which is a reserved value
#define AUDIO_ADTS ADTS_AUDIO_STREAM_TYPE
#define AUDIO_L2 MPEG2_AUDIO_STREAM_TYPE
#define AUDIO_AC3 ATSC_DOLBY_AUDIO_STREAM_TYPE
#define AUDIO_ADTS_MPEG2 0x100
#define AUDIO_ADTS_MPEG4 0x101
@ -54,6 +55,7 @@ typedef struct audio_frame *audio_frame_p;
(x)==AUDIO_ADTS_MPEG2?"ADTS-MPEG2": \
(x)==AUDIO_ADTS_MPEG4?"ADTS-MPEG4": \
(x)==AUDIO_L2 ?"MPEG2": \
(x)==AUDIO_AC3 ?"ATSC-AC3": \
"???")

Wyświetl plik

@ -55,6 +55,8 @@
#define ADTS_SAMPLES_PER_FRAME 1024
// For MPEG-1 audio layer 2, this is 1152
#define L2_SAMPLES_PER_FRAME 1152
// For AC-3 this is 256 * 6
#define AC3_SAMPLES_PER_FRAME (256 * 6)
// ------------------------------------------------------------
#define TEST_PTS_DTS 0
@ -186,6 +188,9 @@ static int merge_with_avs(avs_context_p video_context,
case AUDIO_L2:
prog_type[1] = MPEG2_AUDIO_STREAM_TYPE;
break;
case AUDIO_AC3:
prog_type[1] = ATSC_DOLBY_AUDIO_STREAM_TYPE;
break;
default: // what else can we do?
prog_type[1] = ADTS_AUDIO_STREAM_TYPE;
break;
@ -419,6 +424,9 @@ static int merge_with_h264(access_unit_context_p video_context,
case AUDIO_L2:
prog_type[1] = MPEG2_AUDIO_STREAM_TYPE;
break;
case AUDIO_AC3:
prog_type[1] = ATSC_DOLBY_AUDIO_STREAM_TYPE;
break;
default: // what else can we do?
prog_type[1] = ADTS_AUDIO_STREAM_TYPE;
break;
@ -610,6 +618,7 @@ static void print_usage()
" -l2 The audio stream is MPEG layer 2 audio\n"
" -mp2adts The audio stream is MPEG-2 style ADTS regardless of ID bit\n"
" -mp4adts The audio stream is MPEG-4 style ADTS regardless of ID bit\n"
" -ac3 The audio stream is Dolby AC-3 in ATSC\n"
"\n"
" -patpmtfreq <f> PAT and PMT will be inserted every <f> video frames. \n"
" by default, f = 0 and PAT/PMT are inserted only at \n"
@ -618,8 +627,8 @@ static void print_usage()
"Limitations\n"
"===========\n"
"For the moment, the video input must be H.264 or AVS, and the audio input\n"
"ADTS or MPEG layer 2. Also, the audio is assumed to have a constant\n"
"number of samples per frame.\n"
"ADTS, AC-3 ATSC or MPEG layer 2. Also, the audio is assumed to have a\n"
"constant number of samples per frame.\n"
);
}
@ -712,6 +721,10 @@ int main(int argc, char **argv)
{
audio_type = AUDIO_L2;
}
else if (!strcmp("-ac3", argv[ii]))
{
audio_type = AUDIO_AC3;
}
else if (!strcmp("-h264",argv[ii]))
{
video_type = VIDEO_H264;
@ -851,6 +864,9 @@ int main(int argc, char **argv)
case AUDIO_L2:
audio_samples_per_frame = L2_SAMPLES_PER_FRAME;
break;
case AUDIO_AC3:
audio_samples_per_frame = AC3_SAMPLES_PER_FRAME;
break;
default: // hmm - or we could give up...
audio_samples_per_frame = ADTS_SAMPLES_PER_FRAME;
break;