1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

Merge remote-tracking branch 'newdev/master'

* newdev/master:
  mov: set audio service type for AC-3 from bitstream mode in the 'dac3' atom.
  Get audio_service_type for AC-3 based on bitstream mode in the AC-3 parser and decoder, and vice-versa for the AC-3 encoder.
  Use audio_service_type to set stream disposition.
  Add APIchanges entry for audio_service_type.
  Add audio_service_type field to AVCodecContext for encoding and reporting of the service type in the audio bitstream.
  configure: in check_ld, place new -l flags before existing ones
  support @heading, @subheading, @subsubheading, and @subsubsection in texi2pod.pl
  doc: update build system documentation
  aacenc: indentation
  aacenc: fix the side calculation in search_for_ms
  vp8.c: rename EDGE_* to VP8_EDGE_*.

Conflicts:
	doc/APIchanges
	libavcodec/avcodec.h
	libavcodec/version.h
	libavcodec/vp8.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2011-03-26 02:42:40 +01:00
commit 27ef7b1bcd
22 changed files with 190 additions and 31 deletions

2
configure vendored
View File

@ -642,7 +642,7 @@ check_ld(){
test "${f}" = "${f#-l}" && flags="$flags $f" || libs="$libs $f" test "${f}" = "${f#-l}" && flags="$flags $f" || libs="$libs $f"
done done
check_cc $($filter_cflags $flags) || return check_cc $($filter_cflags $flags) || return
check_cmd $ld $LDFLAGS $flags -o $TMPE $TMPO $extralibs $libs check_cmd $ld $LDFLAGS $flags -o $TMPE $TMPO $libs $extralibs
} }
check_cppflags(){ check_cppflags(){

View File

@ -12,6 +12,9 @@ libavutil: 2009-03-08
API changes, most recent first: API changes, most recent first:
2011-03-25 - 34b47d7 - lavc 52.115.0 - AVCodecContext.audio_service_type
Add audio_service_type field to AVCodecContext.
2011-XX-XX - XXXXXXX - lavu XX.XXX.X - pixfmt.h 2011-XX-XX - XXXXXXX - lavu XX.XXX.X - pixfmt.h
Add PIX_FMT_BGR48LE and PIX_FMT_BGR48BE pixel formats Add PIX_FMT_BGR48LE and PIX_FMT_BGR48BE pixel formats

View File

@ -1,11 +1,38 @@
FFmpeg currently uses a custom build system, this text attempts to document FFmpeg currently uses a custom build system, this text attempts to document
some of its obscure features and options. some of its obscure features and options.
Options to make: Makefile variables:
make V=1 <target>
Build target with verbosity 1, instead of 1, 2 can be used too V
make SAMPLES=<path to the fate samples> <target> Disable the default terse mode, the full command issued by make and its
specify the path to the fate samples at make time output will be shown on the screen.
DESTDIR
Destination directory for the install targets, useful to prepare packages
or install Libav in cross-environments.
Makefile targets:
all
Default target, builds all the libraries and the executables.
fate
Run the fate test suite, note you must have installed it
fate-list
Will list all fate/regression test targets
install
Install headers, libraries and programs.
libavformat/output-example
Build the libavformat basic example.
libavcodec/api-example
Build the libavcodec basic example.
libswscale/swscale-test
Build the swscale self-test (useful also as example).
Useful standard make commands: Useful standard make commands:
@ -21,17 +48,3 @@ make -k
continue build in case of errors, this is useful for the regression tests continue build in case of errors, this is useful for the regression tests
sometimes but note it will still not run all reg tests. sometimes but note it will still not run all reg tests.
Targets to make:
fate-list
Will list all fate/regression test targets
fate
Run the fate test suite, note you must have installed it
Setting up local fate:
use the following command to get the fate test samples
rsync -aL rsync://rsync.mplayerhq.hu:/samples/fate-suite/ fate/fate-suite
pass --samples=<path to the samples> to configure or pass the path with the
SAMPLES variable to make

45
doc/fate.txt Normal file
View File

@ -0,0 +1,45 @@
FATE Automated Testing Environment
FATE provides a regression testsuite that can be run locally or configured
to send reports to fate.ffmpeg.org.
In order to run, it needs a large amount of data (samples and references)
that is provided separately from the actual source distribution.
Use the following command to get the fate test samples
# rsync -aL rsync://rsync.mplayerhq.hu:/samples/fate-suite/ fate/fate-suite
To inform the build system about the testsuite location, pass
`--samples=<path to the samples>` to configure or set the SAMPLES Make
variable or the FATE_SAMPLES environment variable to a suitable value.
For information on how to set up FATE to send results to the official FFmpeg
testing framework, please refer to the following wiki page:
http://wiki.multimedia.cx/index.php?title=FATE
FATE Makefile targets:
fate-list
Will list all fate/regression test targets.
fate
Run the FATE test suite (requires the fate-suite dataset).
Fate Makefile variables:
V
Verbosity level, can be set to 0, 1 or 2.
* 0: show just the test arguments
* 1: show just the command used in the test
* 2: show everything
SAMPLES
Specify or override the path to the FATE samples at make time, it has a
meaning only while running the regression tests.
THREADS
Specify how many threads to use while running regression tests, it is
quite useful to detect thread-related regressions.
Example:
make V=1 SAMPLES=/var/fate/samples THREADS=2 fate

View File

@ -586,6 +586,28 @@ Set the ISO 639 language code (3 letters) of the current audio stream.
@table @option @table @option
@item -atag @var{fourcc/tag} @item -atag @var{fourcc/tag}
Force audio tag/fourcc. Force audio tag/fourcc.
@item -audio_service_type @var{type}
Set the type of service that the audio stream contains.
@table @option
@item ma
Main Audio Service (default)
@item ef
Effects
@item vi
Visually Impaired
@item hi
Hearing Impaired
@item di
Dialogue
@item co
Commentary
@item em
Emergency
@item vo
Voice Over
@item ka
Karaoke
@end table
@item -absf @var{bitstream_filter} @item -absf @var{bitstream_filter}
Bitstream filters available are "dump_extra", "remove_extra", "noise", "mp3comp", "mp3decomp". Bitstream filters available are "dump_extra", "remove_extra", "noise", "mp3comp", "mp3decomp".
@end table @end table

View File

@ -231,10 +231,12 @@ while(<$inf>) {
# Single line command handlers. # Single line command handlers.
/^\@(?:section|unnumbered|unnumberedsec|center)\s+(.+)$/ /^\@(?:section|unnumbered|unnumberedsec|center|heading)\s+(.+)$/
and $_ = "\n=head2 $1\n"; and $_ = "\n=head2 $1\n";
/^\@subsection\s+(.+)$/ /^\@(?:subsection|subheading)\s+(.+)$/
and $_ = "\n=head3 $1\n"; and $_ = "\n=head3 $1\n";
/^\@(?:subsubsection|subsubheading)\s+(.+)$/
and $_ = "\n=head4 $1\n";
# Block command handlers: # Block command handlers:
/^\@itemize\s*(\@[a-z]+|\*|-)?/ and do { /^\@itemize\s*(\@[a-z]+|\*|-)?/ and do {

View File

@ -2123,6 +2123,7 @@ static int transcode(AVFormatContext **output_files,
codec->sample_rate = icodec->sample_rate; codec->sample_rate = icodec->sample_rate;
codec->channels = icodec->channels; codec->channels = icodec->channels;
codec->frame_size = icodec->frame_size; codec->frame_size = icodec->frame_size;
codec->audio_service_type = icodec->audio_service_type;
codec->block_align= icodec->block_align; codec->block_align= icodec->block_align;
if(codec->block_align == 1 && codec->codec_id == CODEC_ID_MP3) if(codec->block_align == 1 && codec->codec_id == CODEC_ID_MP3)
codec->block_align= 0; codec->block_align= 0;

View File

@ -94,6 +94,7 @@ get_next:
avctx->channel_layout = s->channel_layout; avctx->channel_layout = s->channel_layout;
} }
avctx->frame_size = s->samples; avctx->frame_size = s->samples;
avctx->audio_service_type = s->service_type;
} }
avctx->bit_rate = s->bit_rate; avctx->bit_rate = s->bit_rate;

View File

@ -49,6 +49,7 @@ typedef struct AACAC3ParseContext {
int bit_rate; int bit_rate;
int samples; int samples;
int64_t channel_layout; int64_t channel_layout;
int service_type;
int remaining_size; int remaining_size;
uint64_t state; uint64_t state;

View File

@ -817,7 +817,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
int prevsc = sce->sf_idx[w*16+g]; int prevsc = sce->sf_idx[w*16+g];
if (dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60) { if (dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60) {
if (find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]-1)) if (find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]-1))
sce->sf_idx[w*16+g]--; sce->sf_idx[w*16+g]--;
else //Try to make sure there is some energy in every band else //Try to make sure there is some energy in every band
sce->sf_idx[w*16+g]-=2; sce->sf_idx[w*16+g]-=2;
} }
@ -1057,7 +1057,7 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe,
for (i = 0; i < sce0->ics.swb_sizes[g]; i++) { for (i = 0; i < sce0->ics.swb_sizes[g]; i++) {
M[i] = (sce0->coeffs[start+w2*128+i] M[i] = (sce0->coeffs[start+w2*128+i]
+ sce1->coeffs[start+w2*128+i]) * 0.5; + sce1->coeffs[start+w2*128+i]) * 0.5;
S[i] = sce0->coeffs[start+w2*128+i] S[i] = M[i]
- sce1->coeffs[start+w2*128+i]; - sce1->coeffs[start+w2*128+i];
} }
abs_pow34_v(L34, sce0->coeffs+start+w2*128, sce0->ics.swb_sizes[g]); abs_pow34_v(L34, sce0->coeffs+start+w2*128, sce0->ics.swb_sizes[g]);

View File

@ -87,6 +87,7 @@ typedef struct {
uint16_t crc1; uint16_t crc1;
uint8_t sr_code; uint8_t sr_code;
uint8_t bitstream_id; uint8_t bitstream_id;
uint8_t bitstream_mode;
uint8_t channel_mode; uint8_t channel_mode;
uint8_t lfe_on; uint8_t lfe_on;
uint8_t frame_type; uint8_t frame_type;

View File

@ -69,7 +69,7 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr)
skip_bits(gbc, 5); // skip bsid, already got it skip_bits(gbc, 5); // skip bsid, already got it
skip_bits(gbc, 3); // skip bitstream mode hdr->bitstream_mode = get_bits(gbc, 3);
hdr->channel_mode = get_bits(gbc, 3); hdr->channel_mode = get_bits(gbc, 3);
if(hdr->channel_mode == AC3_CHMODE_STEREO) { if(hdr->channel_mode == AC3_CHMODE_STEREO) {
@ -151,6 +151,9 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info,
hdr_info->channels = hdr.channels; hdr_info->channels = hdr.channels;
hdr_info->channel_layout = hdr.channel_layout; hdr_info->channel_layout = hdr.channel_layout;
hdr_info->samples = hdr.num_blocks * 256; hdr_info->samples = hdr.num_blocks * 256;
hdr_info->service_type = hdr.bitstream_mode;
if (hdr.bitstream_mode == 0x7 && hdr.channels > 1)
hdr_info->service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
if(hdr.bitstream_id>10) if(hdr.bitstream_id>10)
hdr_info->codec_id = CODEC_ID_EAC3; hdr_info->codec_id = CODEC_ID_EAC3;
else if (hdr_info->codec_id == CODEC_ID_NONE) else if (hdr_info->codec_id == CODEC_ID_NONE)

View File

@ -273,6 +273,7 @@ static int parse_frame_header(AC3DecodeContext *s)
/* get decoding parameters from header info */ /* get decoding parameters from header info */
s->bit_alloc_params.sr_code = hdr.sr_code; s->bit_alloc_params.sr_code = hdr.sr_code;
s->bitstream_mode = hdr.bitstream_mode;
s->channel_mode = hdr.channel_mode; s->channel_mode = hdr.channel_mode;
s->channel_layout = hdr.channel_layout; s->channel_layout = hdr.channel_layout;
s->lfe_on = hdr.lfe_on; s->lfe_on = hdr.lfe_on;
@ -1399,6 +1400,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
if(s->out_channels < s->channels) if(s->out_channels < s->channels)
s->output_mode = s->out_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; s->output_mode = s->out_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO;
} }
/* set audio service type based on bitstream mode for AC-3 */
avctx->audio_service_type = s->bitstream_mode;
if (s->bitstream_mode == 0x7 && s->channels > 1)
avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
/* decode the audio blocks */ /* decode the audio blocks */
channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on]; channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on];

View File

@ -79,6 +79,7 @@ typedef struct {
int bit_rate; ///< stream bit rate, in bits-per-second int bit_rate; ///< stream bit rate, in bits-per-second
int sample_rate; ///< sample frequency, in Hz int sample_rate; ///< sample frequency, in Hz
int num_blocks; ///< number of audio blocks int num_blocks; ///< number of audio blocks
int bitstream_mode; ///< bitstream mode (bsmod)
int channel_mode; ///< channel mode (acmod) int channel_mode; ///< channel mode (acmod)
int channel_layout; ///< channel layout int channel_layout; ///< channel layout
int lfe_on; ///< lfe channel in use int lfe_on; ///< lfe channel in use

View File

@ -1657,6 +1657,18 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s)
if (s->cutoff > (s->sample_rate >> 1)) if (s->cutoff > (s->sample_rate >> 1))
s->cutoff = s->sample_rate >> 1; s->cutoff = s->sample_rate >> 1;
/* validate audio service type / channels combination */
if ((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_KARAOKE &&
avctx->channels == 1) ||
((avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_COMMENTARY ||
avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_EMERGENCY ||
avctx->audio_service_type == AV_AUDIO_SERVICE_TYPE_VOICE_OVER)
&& avctx->channels > 1)) {
av_log(avctx, AV_LOG_ERROR, "invalid audio service type for the "
"specified number of channels\n");
return AVERROR(EINVAL);
}
return 0; return 0;
} }
@ -1799,7 +1811,9 @@ static av_cold int ac3_encode_init(AVCodecContext *avctx)
return ret; return ret;
s->bitstream_id = 8 + s->bit_alloc.sr_shift; s->bitstream_id = 8 + s->bit_alloc.sr_shift;
s->bitstream_mode = 0; /* complete main audio service */ s->bitstream_mode = avctx->audio_service_type;
if (s->bitstream_mode == AV_AUDIO_SERVICE_TYPE_KARAOKE)
s->bitstream_mode = 0x7;
s->frame_size_min = 2 * ff_ac3_frame_size_tab[s->frame_size_code][s->bit_alloc.sr_code]; s->frame_size_min = 2 * ff_ac3_frame_size_tab[s->frame_size_code][s->bit_alloc.sr_code];
s->bits_written = 0; s->bits_written = 0;

View File

@ -546,6 +546,19 @@ enum AVLPCType {
AV_LPC_TYPE_NB , ///< Not part of ABI AV_LPC_TYPE_NB , ///< Not part of ABI
}; };
enum AVAudioServiceType {
AV_AUDIO_SERVICE_TYPE_MAIN = 0,
AV_AUDIO_SERVICE_TYPE_EFFECTS = 1,
AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED = 2,
AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED = 3,
AV_AUDIO_SERVICE_TYPE_DIALOGUE = 4,
AV_AUDIO_SERVICE_TYPE_COMMENTARY = 5,
AV_AUDIO_SERVICE_TYPE_EMERGENCY = 6,
AV_AUDIO_SERVICE_TYPE_VOICE_OVER = 7,
AV_AUDIO_SERVICE_TYPE_KARAOKE = 8,
AV_AUDIO_SERVICE_TYPE_NB , ///< Not part of ABI
};
typedef struct RcOverride{ typedef struct RcOverride{
int start_frame; int start_frame;
int end_frame; int end_frame;
@ -2875,6 +2888,13 @@ typedef struct AVCodecContext {
*/ */
uint64_t vbv_delay; uint64_t vbv_delay;
/**
* Type of service that the audio stream conveys.
* - encoding: Set by user.
* - decoding: Set by libavcodec.
*/
enum AVAudioServiceType audio_service_type;
/** /**
* Current statistics for PTS correction. * Current statistics for PTS correction.
* - decoding: maintained and used by libavcodec, not intended to be used by user apps * - decoding: maintained and used by libavcodec, not intended to be used by user apps

View File

@ -410,7 +410,7 @@ int ff_eac3_parse_header(AC3DecodeContext *s)
/* informational metadata */ /* informational metadata */
if (get_bits1(gbc)) { if (get_bits1(gbc)) {
skip_bits(gbc, 3); // skip bit stream mode s->bitstream_mode = get_bits(gbc, 3);
skip_bits(gbc, 2); // skip copyright bit and original bitstream bit skip_bits(gbc, 2); // skip copyright bit and original bitstream bit
if (s->channel_mode == AC3_CHMODE_STEREO) { if (s->channel_mode == AC3_CHMODE_STEREO) {
skip_bits(gbc, 4); // skip Dolby surround and headphone mode skip_bits(gbc, 4); // skip Dolby surround and headphone mode

View File

@ -436,6 +436,16 @@ static const AVOption options[]={
{"slice", NULL, 0, FF_OPT_TYPE_CONST, FF_THREAD_SLICE, INT_MIN, INT_MAX, V|E|D, "thread_type"}, {"slice", NULL, 0, FF_OPT_TYPE_CONST, FF_THREAD_SLICE, INT_MIN, INT_MAX, V|E|D, "thread_type"},
{"frame", NULL, 0, FF_OPT_TYPE_CONST, FF_THREAD_FRAME, INT_MIN, INT_MAX, V|E|D, "thread_type"}, {"frame", NULL, 0, FF_OPT_TYPE_CONST, FF_THREAD_FRAME, INT_MIN, INT_MAX, V|E|D, "thread_type"},
{"vbv_delay", "initial buffer fill time in periods of 27Mhz clock", 0, FF_OPT_TYPE_INT64, 0, 0, INT64_MAX}, {"vbv_delay", "initial buffer fill time in periods of 27Mhz clock", 0, FF_OPT_TYPE_INT64, 0, 0, INT64_MAX},
{"audio_service_type", "audio service type", OFFSET(audio_service_type), FF_OPT_TYPE_INT, AV_AUDIO_SERVICE_TYPE_MAIN, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"},
{"ma", "Main Audio Service", 0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_MAIN, INT_MIN, INT_MAX, A|E, "audio_service_type"},
{"ef", "Effects", 0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_EFFECTS, INT_MIN, INT_MAX, A|E, "audio_service_type"},
{"vi", "Visually Impaired", 0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED, INT_MIN, INT_MAX, A|E, "audio_service_type"},
{"hi", "Hearing Impaired", 0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED, INT_MIN, INT_MAX, A|E, "audio_service_type"},
{"di", "Dialogue", 0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_DIALOGUE, INT_MIN, INT_MAX, A|E, "audio_service_type"},
{"co", "Commentary", 0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_COMMENTARY, INT_MIN, INT_MAX, A|E, "audio_service_type"},
{"em", "Emergency", 0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_EMERGENCY, INT_MIN, INT_MAX, A|E, "audio_service_type"},
{"vo", "Voice Over", 0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_VOICE_OVER, INT_MIN, INT_MAX, A|E, "audio_service_type"},
{"ka", "Karaoke", 0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_KARAOKE, INT_MIN, INT_MAX, A|E, "audio_service_type"},
{NULL}, {NULL},
}; };

View File

@ -21,8 +21,8 @@
#define AVCODEC_VERSION_H #define AVCODEC_VERSION_H
#define LIBAVCODEC_VERSION_MAJOR 52 #define LIBAVCODEC_VERSION_MAJOR 52
#define LIBAVCODEC_VERSION_MINOR 114 #define LIBAVCODEC_VERSION_MINOR 115
#define LIBAVCODEC_VERSION_MICRO 1 #define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \ LIBAVCODEC_VERSION_MINOR, \

View File

@ -512,7 +512,7 @@ void decode_mvs(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y)
mb->mode = VP8_MVMODE_MV; mb->mode = VP8_MVMODE_MV;
/* If we have three distinct MVs, merge first and last if they're the same */ /* If we have three distinct MVs, merge first and last if they're the same */
if (cnt[CNT_SPLITMV] && AV_RN32A(&near_mv[1+VP8_EDGE_TOP]) == AV_RN32A(&near_mv[1+VP8_EDGE_TOPLEFT])) if (cnt[CNT_SPLITMV] && AV_RN32A(&near_mv[1 + VP8_EDGE_TOP]) == AV_RN32A(&near_mv[1 + VP8_EDGE_TOPLEFT]))
cnt[CNT_NEAREST] += 1; cnt[CNT_NEAREST] += 1;
/* Swap near and nearest if necessary */ /* Swap near and nearest if necessary */

View File

@ -492,16 +492,20 @@ static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{ {
AVStream *st; AVStream *st;
int ac3info, acmod, lfeon; int ac3info, acmod, lfeon, bsmod;
if (c->fc->nb_streams < 1) if (c->fc->nb_streams < 1)
return 0; return 0;
st = c->fc->streams[c->fc->nb_streams-1]; st = c->fc->streams[c->fc->nb_streams-1];
ac3info = avio_rb24(pb); ac3info = avio_rb24(pb);
bsmod = (ac3info >> 14) & 0x7;
acmod = (ac3info >> 11) & 0x7; acmod = (ac3info >> 11) & 0x7;
lfeon = (ac3info >> 10) & 0x1; lfeon = (ac3info >> 10) & 0x1;
st->codec->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon; st->codec->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
st->codec->audio_service_type = bsmod;
if (st->codec->channels > 1 && bsmod == 0x7)
st->codec->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
return 0; return 0;
} }

View File

@ -2445,6 +2445,19 @@ int av_find_stream_info(AVFormatContext *ic)
}else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
if(!st->codec->bits_per_coded_sample) if(!st->codec->bits_per_coded_sample)
st->codec->bits_per_coded_sample= av_get_bits_per_sample(st->codec->codec_id); st->codec->bits_per_coded_sample= av_get_bits_per_sample(st->codec->codec_id);
// set stream disposition based on audio service type
switch (st->codec->audio_service_type) {
case AV_AUDIO_SERVICE_TYPE_EFFECTS:
st->disposition = AV_DISPOSITION_CLEAN_EFFECTS; break;
case AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED:
st->disposition = AV_DISPOSITION_VISUAL_IMPAIRED; break;
case AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED:
st->disposition = AV_DISPOSITION_HEARING_IMPAIRED; break;
case AV_AUDIO_SERVICE_TYPE_COMMENTARY:
st->disposition = AV_DISPOSITION_COMMENT; break;
case AV_AUDIO_SERVICE_TYPE_KARAOKE:
st->disposition = AV_DISPOSITION_KARAOKE; break;
}
} }
} }