aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/mpeg.c
diff options
context:
space:
mode:
authorCarl Eugen Hoyos <cehoyos@ag.or.at>2013-03-27 01:48:07 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-03-27 02:32:26 +0100
commit92a9a3020d2c8276de15d8dd5b8d8787e15bb146 (patch)
tree2a44337643a623d2f477de7300fc7c62d873c8bf /libavformat/mpeg.c
parent7857ddceecdd683a41ba5c57e662232c1917e444 (diff)
downloadffmpeg-92a9a3020d2c8276de15d8dd5b8d8787e15bb146.tar.gz
Support pcm_mulaw in Hikvision CCTV mpeg program streams.
Fixes decoding the sample from videolan trac ticket #8344.
Diffstat (limited to 'libavformat/mpeg.c')
-rw-r--r--libavformat/mpeg.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index f36f0db727..7d4785b59a 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -110,6 +110,7 @@ typedef struct MpegDemuxContext {
unsigned char psm_es_type[256];
int sofdec;
int dvd;
+ int imkh_cctv;
#if CONFIG_VOBSUB_DEMUXER
AVFormatContext *sub_ctx;
FFDemuxSubtitlesQueue q;
@@ -119,22 +120,18 @@ typedef struct MpegDemuxContext {
static int mpegps_read_header(AVFormatContext *s)
{
MpegDemuxContext *m = s->priv_data;
- const char *sofdec = "Sofdec";
- int v, i = 0;
+ char buffer[7];
int64_t last_pos = avio_tell(s->pb);
m->header_state = 0xff;
s->ctx_flags |= AVFMTCTX_NOHEADER;
- m->sofdec = -1;
- do {
- v = avio_r8(s->pb);
- m->sofdec++;
- } while (v == sofdec[i] && i++ < 6);
-
- m->sofdec = (m->sofdec == 6) ? 1 : 0;
-
- if (!m->sofdec)
+ avio_get_str(s->pb, 6, buffer, sizeof(buffer));
+ if (!memcmp("IMKH", buffer, 4)) {
+ m->imkh_cctv = 1;
+ } else if (!memcmp("Sofdec", buffer, 6)) {
+ m->sofdec = 1;
+ } else
avio_seek(s->pb, last_pos, SEEK_SET);
/* no need to do more */
@@ -506,6 +503,9 @@ static int mpegps_read_packet(AVFormatContext *s,
} else if(es_type == STREAM_TYPE_AUDIO_AC3){
codec_id = AV_CODEC_ID_AC3;
type = AVMEDIA_TYPE_AUDIO;
+ } else if(m->imkh_cctv && es_type == 0x91){
+ codec_id = AV_CODEC_ID_PCM_MULAW;
+ type = AVMEDIA_TYPE_AUDIO;
} else if (startcode >= 0x1e0 && startcode <= 0x1ef) {
static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 };
unsigned char buf[8];
@@ -564,6 +564,11 @@ static int mpegps_read_packet(AVFormatContext *s,
st->id = startcode;
st->codec->codec_type = type;
st->codec->codec_id = codec_id;
+ if (st->codec->codec_id == AV_CODEC_ID_PCM_MULAW) {
+ st->codec->channels = 1;
+ st->codec->channel_layout = AV_CH_LAYOUT_MONO;
+ st->codec->sample_rate = 8000;
+ }
st->request_probe = request_probe;
if (codec_id != AV_CODEC_ID_PCM_S16BE)
st->need_parsing = AVSTREAM_PARSE_FULL;