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 # All of our non-program source files
SRCS = \ SRCS = \
accessunit.c \ accessunit.c \
ac3.c \
adts.c \ adts.c \
avs.c \ avs.c \
bitdata.c \ bitdata.c \
@ -111,6 +112,7 @@ SRCS = \
OBJS = \ OBJS = \
accessunit.o \ accessunit.o \
avs.o \ avs.o \
ac3.o \
adts.o \ adts.o \
bitdata.o \ bitdata.o \
es.o \ es.o \
@ -149,6 +151,7 @@ PROG_OBJS = \
$(OBJDIR)/tsreport.o \ $(OBJDIR)/tsreport.o \
$(OBJDIR)/tsserve.o \ $(OBJDIR)/tsserve.o \
$(OBJDIR)/ts_packet_insert.o \ $(OBJDIR)/ts_packet_insert.o \
$(OBJDIR)/m2ts2ts.o
$(OBJDIR)/pcapreport.o $(OBJDIR)/pcapreport.o
#\ #\
# $(OBJDIR)/test_ps.o # $(OBJDIR)/test_ps.o
@ -183,6 +186,7 @@ PROGS = \
$(BINDIR)/tsplay \ $(BINDIR)/tsplay \
$(BINDIR)/tsserve \ $(BINDIR)/tsserve \
$(BINDIR)/ts_packet_insert \ $(BINDIR)/ts_packet_insert \
$(BINDIR)/m2ts2ts
$(BINDIR)/pcapreport $(BINDIR)/pcapreport
#\ #\
# $(BINDIR)/test_ps # $(BINDIR)/test_ps
@ -266,6 +270,8 @@ $(BINDIR)/ts2ps: $(OBJDIR)/ts2ps.o $(LIB)
$(BINDIR)/ts_packet_insert: $(OBJDIR)/ts_packet_insert.o $(LIB) $(BINDIR)/ts_packet_insert: $(OBJDIR)/ts_packet_insert.o $(LIB)
$(CC) $< -o $(BINDIR)/ts_packet_insert $(LDFLAGS) $(LIBOPTS) $(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) $(BINDIR)/pcapreport: $(OBJDIR)/pcapreport.o $(LIB)
$(CC) $< -o $(BINDIR)/pcapreport $(LDFLAGS) $(LIBOPTS) $(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 TSWRITE_H = tswrite_fns.h tswrite_defns.h
REVERSE_H = reverse_fns.h reverse_defns.h REVERSE_H = reverse_fns.h reverse_defns.h
FILTER_H = filter_fns.h filter_defns.h $(REVERSE_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 # Everyone depends upon the basic configuration file
$(LIB)($(OBJS)) $(TEST_OBJS) $(PROG_OBJS): compat.h $(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) $(CC) -c $< -o $@ $(CFLAGS)
$(OBJDIR)/tswrite.o: tswrite.c misc_fns.h version.h $(OBJDIR)/tswrite.o: tswrite.c misc_fns.h version.h
$(CC) -c $< -o $@ $(CFLAGS) $(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 $(OBJDIR)/pcapreport.o: pcapreport.c pcap.h version.h misc_fns.h
$(CC) -c $< -o $@ $(CFLAGS) $(CC) -c $< -o $@ $(CFLAGS)

Wyświetl plik

@ -74,6 +74,7 @@ PROGS = \
$(EXEDIR)\ts2es.exe \ $(EXEDIR)\ts2es.exe \
$(EXEDIR)\es2ts.exe \ $(EXEDIR)\es2ts.exe \
$(EXEDIR)\esreverse.exe \ $(EXEDIR)\esreverse.exe \
$(EXEDIR)\m2ts2ts.exe \
$(EXEDIR)\ps2ts.exe \ $(EXEDIR)\ps2ts.exe \
$(EXEDIR)\psreport.exe \ $(EXEDIR)\psreport.exe \
$(EXEDIR)\stream_type.exe \ $(EXEDIR)\stream_type.exe \
@ -85,6 +86,7 @@ PROGS = \
# Object files for the library # Object files for the library
LIB_OBJS = \ LIB_OBJS = \
$(OBJDIR)\accessunit.obj \ $(OBJDIR)\accessunit.obj \
$(OBJDIR)\ac3.obj \
$(OBJDIR)\adts.obj \ $(OBJDIR)\adts.obj \
$(OBJDIR)\avs.obj \ $(OBJDIR)\avs.obj \
$(OBJDIR)\audio.obj \ $(OBJDIR)\audio.obj \
@ -111,6 +113,7 @@ PROG_OBJS = \
$(OBJDIR)/esmerge.obj \ $(OBJDIR)/esmerge.obj \
$(OBJDIR)/esreport.obj \ $(OBJDIR)/esreport.obj \
$(OBJDIR)/esreverse.obj \ $(OBJDIR)/esreverse.obj \
$(OBJDIR)/m2ts2ts.obj \
$(OBJDIR)/ps2ts.obj \ $(OBJDIR)/ps2ts.obj \
$(OBJDIR)/psreport.obj \ $(OBJDIR)/psreport.obj \
$(OBJDIR)/stream_type.obj \ $(OBJDIR)/stream_type.obj \
@ -153,6 +156,9 @@ $(EXEDIR)\esreport.exe: $(OBJDIR)\esreport.obj $(LIBFILE)
$(EXEDIR)\esreverse.exe: $(OBJDIR)\esreverse.obj $(LIBFILE) $(EXEDIR)\esreverse.exe: $(OBJDIR)\esreverse.obj $(LIBFILE)
link /out:$@ $(LOPT) $** wsock32.lib 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) $(EXEDIR)\stream_type.exe: $(OBJDIR)\stream_type.obj $(LIBFILE)
link /out:$@ $(LOPT) $** wsock32.lib 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 "audio_fns.h"
#include "adts_fns.h" #include "adts_fns.h"
#include "l2audio_fns.h" #include "l2audio_fns.h"
#include "ac3_fns.h"
/* /*
* Build a new generic audio frame datastructure * 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); return read_next_adts_frame(file,frame,0);
case AUDIO_L2: case AUDIO_L2:
return read_next_l2audio_frame(file,frame); return read_next_l2audio_frame(file,frame);
case AUDIO_AC3:
return read_next_ac3_frame(file, frame);
default: default:
fprintf(stderr,"### Unrecognised audio type %d - cannot get next audio frame\n", fprintf(stderr,"### Unrecognised audio type %d - cannot get next audio frame\n",
audio_type); 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_UNKNOWN 0 // which is a reserved value
#define AUDIO_ADTS ADTS_AUDIO_STREAM_TYPE #define AUDIO_ADTS ADTS_AUDIO_STREAM_TYPE
#define AUDIO_L2 MPEG2_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_MPEG2 0x100
#define AUDIO_ADTS_MPEG4 0x101 #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_MPEG2?"ADTS-MPEG2": \
(x)==AUDIO_ADTS_MPEG4?"ADTS-MPEG4": \ (x)==AUDIO_ADTS_MPEG4?"ADTS-MPEG4": \
(x)==AUDIO_L2 ?"MPEG2": \ (x)==AUDIO_L2 ?"MPEG2": \
(x)==AUDIO_AC3 ?"ATSC-AC3": \
"???") "???")

Wyświetl plik

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