mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-28 20:53:54 +02:00
PSM support in MPEG-PS demuxer.
Based on a patch by Leon Woestenberg <leonw at mailcan dot com> Originally committed as revision 4093 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
09c3e44e8a
commit
e3d1cd8ee9
@ -91,6 +91,19 @@ typedef struct {
|
||||
#define DTS_ID 0x8a
|
||||
#define LPCM_ID 0xa0
|
||||
|
||||
#define STREAM_TYPE_VIDEO_MPEG1 0x01
|
||||
#define STREAM_TYPE_VIDEO_MPEG2 0x02
|
||||
#define STREAM_TYPE_AUDIO_MPEG1 0x03
|
||||
#define STREAM_TYPE_AUDIO_MPEG2 0x04
|
||||
#define STREAM_TYPE_PRIVATE_SECTION 0x05
|
||||
#define STREAM_TYPE_PRIVATE_DATA 0x06
|
||||
#define STREAM_TYPE_AUDIO_AAC 0x0f
|
||||
#define STREAM_TYPE_VIDEO_MPEG4 0x10
|
||||
#define STREAM_TYPE_VIDEO_H264 0x1b
|
||||
|
||||
#define STREAM_TYPE_AUDIO_AC3 0x81
|
||||
#define STREAM_TYPE_AUDIO_DTS 0x8a
|
||||
|
||||
static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 };
|
||||
|
||||
#ifdef CONFIG_ENCODERS
|
||||
@ -1268,6 +1281,7 @@ static int mpegps_probe(AVProbeData *p)
|
||||
|
||||
typedef struct MpegDemuxContext {
|
||||
int header_state;
|
||||
unsigned char psm_es_type[256];
|
||||
} MpegDemuxContext;
|
||||
|
||||
static int mpegps_read_header(AVFormatContext *s,
|
||||
@ -1358,6 +1372,40 @@ static int find_prev_start_code(ByteIOContext *pb, int *size_ptr)
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Extracts stream types from a program stream map
|
||||
* According to ISO/IEC 13818-1 ('MPEG-2 Systems') table 2-35
|
||||
*
|
||||
* @return number of bytes occupied by PSM in the bitstream
|
||||
*/
|
||||
static long mpegps_psm_parse(MpegDemuxContext *m, ByteIOContext *pb)
|
||||
{
|
||||
int psm_length, ps_info_length, es_map_length;
|
||||
|
||||
psm_length = get_be16(pb);
|
||||
get_byte(pb);
|
||||
get_byte(pb);
|
||||
ps_info_length = get_be16(pb);
|
||||
|
||||
/* skip program_stream_info */
|
||||
url_fskip(pb, ps_info_length);
|
||||
es_map_length = get_be16(pb);
|
||||
|
||||
/* at least one es available? */
|
||||
while (es_map_length >= 4){
|
||||
unsigned char type = get_byte(pb);
|
||||
unsigned char es_id = get_byte(pb);
|
||||
uint16_t es_info_length = get_be16(pb);
|
||||
/* remember mapping from stream id to stream type */
|
||||
m->psm_es_type[es_id] = type;
|
||||
/* skip program_stream_info */
|
||||
url_fskip(pb, es_info_length);
|
||||
es_map_length -= 4 + es_info_length;
|
||||
}
|
||||
get_be32(pb); /* crc32 */
|
||||
return 2 + psm_length;
|
||||
}
|
||||
|
||||
/* read the next PES header. Return its position in ppos
|
||||
(if not NULL), and its start code, pts and dts.
|
||||
*/
|
||||
@ -1389,6 +1437,11 @@ static int mpegps_read_pes_header(AVFormatContext *s,
|
||||
url_fskip(&s->pb, len);
|
||||
goto redo;
|
||||
}
|
||||
if (startcode == PROGRAM_STREAM_MAP) {
|
||||
mpegps_psm_parse(m, &s->pb);
|
||||
goto redo;
|
||||
}
|
||||
|
||||
/* find matching stream */
|
||||
if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
|
||||
(startcode >= 0x1e0 && startcode <= 0x1ef) ||
|
||||
@ -1463,7 +1516,7 @@ static int mpegps_read_pes_header(AVFormatContext *s,
|
||||
else if( c!= 0xf )
|
||||
goto redo;
|
||||
|
||||
if (startcode == 0x1bd) {
|
||||
if (startcode == PRIVATE_STREAM_1 && !m->psm_es_type[startcode & 0xff]) {
|
||||
if (len < 1)
|
||||
goto redo;
|
||||
startcode = get_byte(&s->pb);
|
||||
@ -1496,8 +1549,9 @@ static int mpegps_read_pes_header(AVFormatContext *s,
|
||||
static int mpegps_read_packet(AVFormatContext *s,
|
||||
AVPacket *pkt)
|
||||
{
|
||||
MpegDemuxContext *m = s->priv_data;
|
||||
AVStream *st;
|
||||
int len, startcode, i, type, codec_id = 0;
|
||||
int len, startcode, i, type, codec_id = 0, es_type;
|
||||
int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work
|
||||
|
||||
redo:
|
||||
@ -1511,7 +1565,35 @@ static int mpegps_read_packet(AVFormatContext *s,
|
||||
if (st->id == startcode)
|
||||
goto found;
|
||||
}
|
||||
if (startcode >= 0x1e0 && startcode <= 0x1ef) {
|
||||
|
||||
es_type = m->psm_es_type[startcode & 0xff];
|
||||
if(es_type > 0){
|
||||
if(es_type == STREAM_TYPE_VIDEO_MPEG1){
|
||||
codec_id = CODEC_ID_MPEG2VIDEO;
|
||||
type = CODEC_TYPE_VIDEO;
|
||||
} else if(es_type == STREAM_TYPE_VIDEO_MPEG2){
|
||||
codec_id = CODEC_ID_MPEG2VIDEO;
|
||||
type = CODEC_TYPE_VIDEO;
|
||||
} else if(es_type == STREAM_TYPE_AUDIO_MPEG1 ||
|
||||
es_type == STREAM_TYPE_AUDIO_MPEG2){
|
||||
codec_id = CODEC_ID_MP3;
|
||||
type = CODEC_TYPE_AUDIO;
|
||||
} else if(es_type == STREAM_TYPE_AUDIO_AAC){
|
||||
codec_id = CODEC_ID_AAC;
|
||||
type = CODEC_TYPE_AUDIO;
|
||||
} else if(es_type == STREAM_TYPE_VIDEO_MPEG4){
|
||||
codec_id = CODEC_ID_MPEG4;
|
||||
type = CODEC_TYPE_VIDEO;
|
||||
} else if(es_type == STREAM_TYPE_VIDEO_H264){
|
||||
codec_id = CODEC_ID_H264;
|
||||
type = CODEC_TYPE_VIDEO;
|
||||
} else if(es_type == STREAM_TYPE_AUDIO_AC3){
|
||||
codec_id = CODEC_ID_AC3;
|
||||
type = CODEC_TYPE_AUDIO;
|
||||
} else {
|
||||
goto skip;
|
||||
}
|
||||
} else if (startcode >= 0x1e0 && startcode <= 0x1ef) {
|
||||
type = CODEC_TYPE_VIDEO;
|
||||
codec_id = CODEC_ID_MPEG2VIDEO;
|
||||
} else if (startcode >= 0x1c0 && startcode <= 0x1df) {
|
||||
|
Loading…
Reference in New Issue
Block a user