Originally committed as revision 4448 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
@@ -1423,8 +1423,14 @@ static int output_packet(AVInputStream *ist, int ist_index, | |||
av_free(buffer_to_free); | |||
/* XXX: allocate the subtitles in the codec ? */ | |||
if (subtitle_to_free) { | |||
av_free(subtitle_to_free->bitmap); | |||
av_free(subtitle_to_free->rgba_palette); | |||
if (subtitle_to_free->rects != NULL) { | |||
for (i = 0; i < subtitle_to_free->num_rects; i++) { | |||
av_free(subtitle_to_free->rects[i].bitmap); | |||
av_free(subtitle_to_free->rects[i].rgba_palette); | |||
} | |||
av_freep(&subtitle_to_free->rects); | |||
} | |||
subtitle_to_free->num_rects = 0; | |||
subtitle_to_free = NULL; | |||
} | |||
} | |||
@@ -17,7 +17,7 @@ OBJS= bitstream.o utils.o mem.o allcodecs.o \ | |||
ratecontrol.o adpcm.o eval.o error_resilience.o \ | |||
fft.o mdct.o raw.o golomb.o cabac.o\ | |||
dpcm.o adx.o rational.o faandct.o parser.o g726.o \ | |||
vp3dsp.o integer.o h264idct.o rangecoder.o pnm.o h263.o msmpeg4.o h263dec.o dvdsub.o dvbsub.o | |||
vp3dsp.o integer.o h264idct.o rangecoder.o pnm.o h263.o msmpeg4.o h263dec.o dvdsub.o dvbsub.o dvbsubdec.o | |||
ifeq ($(CONFIG_AASC_DECODER),yes) | |||
OBJS+= aasc.o | |||
@@ -555,6 +555,7 @@ PCM_CODEC(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha); | |||
/* subtitles */ | |||
register_avcodec(&dvdsub_decoder); | |||
register_avcodec(&dvbsub_encoder); | |||
register_avcodec(&dvbsub_decoder); | |||
/* parsers */ | |||
av_register_codec_parser(&mpegvideo_parser); | |||
@@ -574,5 +575,6 @@ PCM_CODEC(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha); | |||
av_register_codec_parser(&ac3_parser); | |||
#endif | |||
av_register_codec_parser(&dvdsub_parser); | |||
av_register_codec_parser(&dvbsub_parser); | |||
} | |||
@@ -1930,18 +1930,23 @@ typedef struct AVPaletteControl { | |||
} AVPaletteControl; | |||
typedef struct AVSubtitle { | |||
uint16_t format; /* 0 = graphics */ | |||
typedef struct AVSubtitleRect { | |||
uint16_t x; | |||
uint16_t y; | |||
uint16_t w; | |||
uint16_t h; | |||
uint16_t nb_colors; | |||
uint32_t start_display_time; /* relative to packet pts, in ms */ | |||
uint32_t end_display_time; /* relative to packet pts, in ms */ | |||
int linesize; | |||
uint32_t *rgba_palette; | |||
uint8_t *bitmap; | |||
} AVSubtitleRect; | |||
typedef struct AVSubtitle { | |||
uint16_t format; /* 0 = graphics */ | |||
uint32_t start_display_time; /* relative to packet pts, in ms */ | |||
uint32_t end_display_time; /* relative to packet pts, in ms */ | |||
uint32_t num_rects; | |||
AVSubtitleRect *rects; | |||
} AVSubtitle; | |||
extern AVCodec ac3_encoder; | |||
@@ -2135,6 +2140,7 @@ extern AVCodec dts_decoder; | |||
/* subtitles */ | |||
extern AVCodec dvdsub_decoder; | |||
extern AVCodec dvbsub_encoder; | |||
extern AVCodec dvbsub_decoder; | |||
/* resample.c */ | |||
@@ -2390,6 +2396,7 @@ extern AVCodecParser pnm_parser; | |||
extern AVCodecParser mpegaudio_parser; | |||
extern AVCodecParser ac3_parser; | |||
extern AVCodecParser dvdsub_parser; | |||
extern AVCodecParser dvbsub_parser; | |||
/* memory */ | |||
void *av_malloc(unsigned int size); | |||
@@ -225,18 +225,9 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, | |||
q = outbuf; | |||
page_id = 1; | |||
region_id = 0; | |||
clut_id = 0; | |||
object_id = 0; | |||
if (h->nb_colors <= 4) { | |||
/* 2 bpp, some decoders do not support it correctly */ | |||
bpp_index = 0; | |||
} else if (h->nb_colors <= 16) { | |||
/* 4 bpp, standard encoding */ | |||
bpp_index = 1; | |||
} else { | |||
if (h->num_rects == 0 || h->rects == NULL) | |||
return -1; | |||
} | |||
*q++ = 0x00; /* subtitle_stream_id */ | |||
@@ -254,108 +245,153 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, | |||
page_state = 2; /* mode change */ | |||
/* page_version = 0 + page_state */ | |||
*q++ = s->object_version | (page_state << 2) | 3; | |||
*q++ = region_id; | |||
*q++ = 0xff; /* reserved */ | |||
putbe16(&q, 0); /* left pos */ | |||
putbe16(&q, 0); /* top pos */ | |||
for (region_id = 0; region_id < h->num_rects; region_id++) { | |||
*q++ = region_id; | |||
*q++ = 0xff; /* reserved */ | |||
putbe16(&q, h->rects[region_id].x); /* left pos */ | |||
putbe16(&q, h->rects[region_id].y); /* top pos */ | |||
} | |||
putbe16(&pseg_len, q - pseg_len - 2); | |||
if (!s->hide_state) { | |||
/* CLUT segment */ | |||
for (clut_id = 0; clut_id < h->num_rects; clut_id++) { | |||
/* CLUT segment */ | |||
if (h->rects[clut_id].nb_colors <= 4) { | |||
/* 2 bpp, some decoders do not support it correctly */ | |||
bpp_index = 0; | |||
} else if (h->rects[clut_id].nb_colors <= 16) { | |||
/* 4 bpp, standard encoding */ | |||
bpp_index = 1; | |||
} else { | |||
return -1; | |||
} | |||
*q++ = 0x0f; /* sync byte */ | |||
*q++ = 0x12; /* CLUT definition segment */ | |||
putbe16(&q, page_id); | |||
pseg_len = q; | |||
q += 2; /* segment length */ | |||
*q++ = clut_id; | |||
*q++ = (0 << 4) | 0xf; /* version = 0 */ | |||
for(i = 0; i < h->rects[clut_id].nb_colors; i++) { | |||
*q++ = i; /* clut_entry_id */ | |||
*q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */ | |||
{ | |||
int a, r, g, b; | |||
a = (h->rects[clut_id].rgba_palette[i] >> 24) & 0xff; | |||
r = (h->rects[clut_id].rgba_palette[i] >> 16) & 0xff; | |||
g = (h->rects[clut_id].rgba_palette[i] >> 8) & 0xff; | |||
b = (h->rects[clut_id].rgba_palette[i] >> 0) & 0xff; | |||
*q++ = RGB_TO_Y_CCIR(r, g, b); | |||
*q++ = RGB_TO_V_CCIR(r, g, b, 0); | |||
*q++ = RGB_TO_U_CCIR(r, g, b, 0); | |||
*q++ = 255 - a; | |||
} | |||
} | |||
putbe16(&pseg_len, q - pseg_len - 2); | |||
} | |||
} | |||
for (region_id = 0; region_id < h->num_rects; region_id++) { | |||
/* region composition segment */ | |||
*q++ = 0x0f; /* sync byte */ | |||
*q++ = 0x12; /* CLUT definition segment */ | |||
if (h->rects[region_id].nb_colors <= 4) { | |||
/* 2 bpp, some decoders do not support it correctly */ | |||
bpp_index = 0; | |||
} else if (h->rects[region_id].nb_colors <= 16) { | |||
/* 4 bpp, standard encoding */ | |||
bpp_index = 1; | |||
} else { | |||
return -1; | |||
} | |||
*q++ = 0x0f; /* sync_byte */ | |||
*q++ = 0x11; /* segment_type */ | |||
putbe16(&q, page_id); | |||
pseg_len = q; | |||
q += 2; /* segment length */ | |||
*q++ = clut_id; | |||
*q++ = (0 << 4) | 0xf; /* version = 0 */ | |||
for(i = 0; i < h->nb_colors; i++) { | |||
*q++ = i; /* clut_entry_id */ | |||
*q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */ | |||
{ | |||
int a, r, g, b; | |||
a = (h->rgba_palette[i] >> 24) & 0xff; | |||
r = (h->rgba_palette[i] >> 16) & 0xff; | |||
g = (h->rgba_palette[i] >> 8) & 0xff; | |||
b = (h->rgba_palette[i] >> 0) & 0xff; | |||
*q++ = RGB_TO_Y_CCIR(r, g, b); | |||
*q++ = RGB_TO_V_CCIR(r, g, b, 0); | |||
*q++ = RGB_TO_U_CCIR(r, g, b, 0); | |||
*q++ = 255 - a; | |||
} | |||
*q++ = region_id; | |||
*q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */ | |||
putbe16(&q, h->rects[region_id].w); /* region width */ | |||
putbe16(&q, h->rects[region_id].h); /* region height */ | |||
*q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03; | |||
*q++ = region_id; /* clut_id == region_id */ | |||
*q++ = 0; /* 8 bit fill colors */ | |||
*q++ = 0x03; /* 4 bit and 2 bit fill colors */ | |||
if (!s->hide_state) { | |||
putbe16(&q, region_id); /* object_id == region_id */ | |||
*q++ = (0 << 6) | (0 << 4); | |||
*q++ = 0; | |||
*q++ = 0xf0; | |||
*q++ = 0; | |||
} | |||
putbe16(&pseg_len, q - pseg_len - 2); | |||
} | |||
/* region composition segment */ | |||
*q++ = 0x0f; /* sync_byte */ | |||
*q++ = 0x11; /* segment_type */ | |||
putbe16(&q, page_id); | |||
pseg_len = q; | |||
q += 2; /* segment length */ | |||
*q++ = region_id; | |||
*q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */ | |||
putbe16(&q, 720); /* region width */ | |||
putbe16(&q, 576); /* region height */ | |||
*q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03; | |||
*q++ = clut_id; | |||
*q++ = 0; /* 8 bit fill colors */ | |||
*q++ = 0x03; /* 4 bit and 2 bit fill colors */ | |||
if (!s->hide_state) { | |||
putbe16(&q, object_id); | |||
*q++ = (0 << 6) | (0 << 4) | ((h->x >> 8) & 0xf); | |||
*q++ = h->x; | |||
*q++ = 0xf0 | ((h->y >> 8) & 0xf); | |||
*q++ = h->y; | |||
} | |||
putbe16(&pseg_len, q - pseg_len - 2); | |||
if (!s->hide_state) { | |||
/* Object Data segment */ | |||
for (object_id = 0; object_id < h->num_rects; object_id++) { | |||
/* Object Data segment */ | |||
if (h->rects[region_id].nb_colors <= 4) { | |||
/* 2 bpp, some decoders do not support it correctly */ | |||
bpp_index = 0; | |||
} else if (h->rects[region_id].nb_colors <= 16) { | |||
/* 4 bpp, standard encoding */ | |||
bpp_index = 1; | |||
} else { | |||
return -1; | |||
} | |||
*q++ = 0x0f; /* sync byte */ | |||
*q++ = 0x13; | |||
putbe16(&q, page_id); | |||
pseg_len = q; | |||
q += 2; /* segment length */ | |||
putbe16(&q, object_id); | |||
*q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0, | |||
onject_coding_method, | |||
non_modifying_color_flag */ | |||
{ | |||
uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr; | |||
void (*dvb_encode_rle)(uint8_t **pq, | |||
const uint8_t *bitmap, int linesize, | |||
int w, int h); | |||
ptop_field_len = q; | |||
q += 2; | |||
pbottom_field_len = q; | |||
q += 2; | |||
if (bpp_index == 0) | |||
dvb_encode_rle = dvb_encode_rle2; | |||
else | |||
dvb_encode_rle = dvb_encode_rle4; | |||
top_ptr = q; | |||
dvb_encode_rle(&q, h->bitmap, h->w * 2, h->w, h->h >> 1); | |||
bottom_ptr = q; | |||
dvb_encode_rle(&q, h->bitmap + h->w, h->w * 2, h->w, h->h >> 1); | |||
putbe16(&ptop_field_len, bottom_ptr - top_ptr); | |||
putbe16(&pbottom_field_len, q - bottom_ptr); | |||
} | |||
*q++ = 0x0f; /* sync byte */ | |||
*q++ = 0x13; | |||
putbe16(&q, page_id); | |||
pseg_len = q; | |||
q += 2; /* segment length */ | |||
putbe16(&pseg_len, q - pseg_len - 2); | |||
putbe16(&q, object_id); | |||
*q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0, | |||
onject_coding_method, | |||
non_modifying_color_flag */ | |||
{ | |||
uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr; | |||
void (*dvb_encode_rle)(uint8_t **pq, | |||
const uint8_t *bitmap, int linesize, | |||
int w, int h); | |||
ptop_field_len = q; | |||
q += 2; | |||
pbottom_field_len = q; | |||
q += 2; | |||
if (bpp_index == 0) | |||
dvb_encode_rle = dvb_encode_rle2; | |||
else | |||
dvb_encode_rle = dvb_encode_rle4; | |||
top_ptr = q; | |||
dvb_encode_rle(&q, h->rects[object_id].bitmap, h->rects[object_id].w * 2, | |||
h->rects[object_id].w, h->rects[object_id].h >> 1); | |||
bottom_ptr = q; | |||
dvb_encode_rle(&q, h->rects[object_id].bitmap + h->rects[object_id].w, | |||
h->rects[object_id].w * 2, h->rects[object_id].w, | |||
h->rects[object_id].h >> 1); | |||
putbe16(&ptop_field_len, bottom_ptr - top_ptr); | |||
putbe16(&pbottom_field_len, q - bottom_ptr); | |||
} | |||
putbe16(&pseg_len, q - pseg_len - 2); | |||
} | |||
} | |||
/* end of display set segment */ | |||
@@ -30,7 +30,10 @@ | |||
synchronisation is lost */ | |||
#define MAX_RESYNC_SIZE 4096 | |||
static int add_pes_stream(MpegTSContext *ts, int pid, int stream_type); | |||
typedef struct PESContext PESContext; | |||
static PESContext* add_pes_stream(MpegTSContext *ts, int pid, int stream_type); | |||
static AVStream* new_pes_av_stream(PESContext *pes, uint32_t code); | |||
enum MpegTSFilterType { | |||
MPEGTS_PES, | |||
@@ -368,8 +371,13 @@ static void pmt_cb(void *opaque, const uint8_t *section, int section_len) | |||
{ | |||
MpegTSContext *ts = opaque; | |||
SectionHeader h1, *h = &h1; | |||
const uint8_t *p, *p_end; | |||
int program_info_length, pcr_pid, pid, stream_type, desc_length; | |||
PESContext *pes; | |||
AVStream *st; | |||
const uint8_t *p, *p_end, *desc_list_end, *desc_end; | |||
int program_info_length, pcr_pid, pid, stream_type; | |||
int desc_list_len, desc_len, desc_tag; | |||
int comp_page, anc_page; | |||
char language[4]; | |||
#ifdef DEBUG_SI | |||
printf("PMT:\n"); | |||
@@ -399,18 +407,57 @@ static void pmt_cb(void *opaque, const uint8_t *section, int section_len) | |||
if (p >= p_end) | |||
return; | |||
for(;;) { | |||
language[0] = 0; | |||
st = 0; | |||
stream_type = get8(&p, p_end); | |||
if (stream_type < 0) | |||
break; | |||
pid = get16(&p, p_end) & 0x1fff; | |||
if (pid < 0) | |||
break; | |||
desc_length = get16(&p, p_end) & 0xfff; | |||
if (desc_length < 0) | |||
desc_list_len = get16(&p, p_end) & 0xfff; | |||
if (desc_list_len < 0) | |||
break; | |||
desc_list_end = p + desc_list_len; | |||
if (desc_list_end > p_end) | |||
break; | |||
p += desc_length; | |||
if (p > p_end) | |||
return; | |||
for(;;) { | |||
desc_tag = get8(&p, desc_list_end); | |||
if (desc_tag < 0) | |||
break; | |||
desc_len = get8(&p, desc_list_end); | |||
desc_end = p + desc_len; | |||
if (desc_end > desc_list_end) | |||
break; | |||
#ifdef DEBUG_SI | |||
printf("tag: 0x%02x len=%d\n", desc_tag, desc_len); | |||
#endif | |||
switch(desc_tag) { | |||
case DVB_SUBT_DESCID: | |||
if (stream_type == STREAM_TYPE_PRIVATE_DATA) | |||
stream_type = STREAM_TYPE_SUBTITLE_DVB; | |||
language[0] = get8(&p, desc_end); | |||
language[1] = get8(&p, desc_end); | |||
language[2] = get8(&p, desc_end); | |||
language[3] = 0; | |||
get8(&p, desc_end); | |||
comp_page = get16(&p, desc_end); | |||
anc_page = get16(&p, desc_end); | |||
break; | |||
case 0x0a: /* ISO 639 language descriptor */ | |||
language[0] = get8(&p, desc_end); | |||
language[1] = get8(&p, desc_end); | |||
language[2] = get8(&p, desc_end); | |||
language[3] = 0; | |||
break; | |||
default: | |||
break; | |||
} | |||
p = desc_end; | |||
} | |||
p = desc_list_end; | |||
#ifdef DEBUG_SI | |||
printf("stream_type=%d pid=0x%x\n", stream_type, pid); | |||
@@ -427,12 +474,28 @@ static void pmt_cb(void *opaque, const uint8_t *section, int section_len) | |||
case STREAM_TYPE_AUDIO_AAC: | |||
case STREAM_TYPE_AUDIO_AC3: | |||
case STREAM_TYPE_AUDIO_DTS: | |||
add_pes_stream(ts, pid, stream_type); | |||
case STREAM_TYPE_SUBTITLE_DVB: | |||
pes = add_pes_stream(ts, pid, stream_type); | |||
if (pes) | |||
st = new_pes_av_stream(pes, 0); | |||
break; | |||
default: | |||
/* we ignore the other streams */ | |||
break; | |||
} | |||
if (st) { | |||
if (language[0] != 0) { | |||
st->language[0] = language[0]; | |||
st->language[1] = language[1]; | |||
st->language[2] = language[2]; | |||
st->language[3] = language[3]; | |||
} | |||
if (stream_type == STREAM_TYPE_SUBTITLE_DVB) { | |||
st->codec.sub_id = (anc_page << 16) | comp_page; | |||
} | |||
} | |||
} | |||
/* all parameters are there */ | |||
ts->set_service_cb(ts->set_service_opaque, 0); | |||
@@ -653,7 +716,7 @@ enum MpegTSState { | |||
#define PES_START_SIZE 9 | |||
#define MAX_PES_HEADER_SIZE (9 + 255) | |||
typedef struct PESContext { | |||
struct PESContext { | |||
int pid; | |||
int stream_type; | |||
MpegTSContext *ts; | |||
@@ -666,7 +729,7 @@ typedef struct PESContext { | |||
int pes_header_size; | |||
int64_t pts, dts; | |||
uint8_t header[MAX_PES_HEADER_SIZE]; | |||
} PESContext; | |||
}; | |||
static int64_t get_pts(const uint8_t *p) | |||
{ | |||
@@ -687,9 +750,8 @@ static void mpegts_push_data(void *opaque, | |||
{ | |||
PESContext *pes = opaque; | |||
MpegTSContext *ts = pes->ts; | |||
AVStream *st; | |||
const uint8_t *p; | |||
int len, code, codec_type, codec_id; | |||
int len, code; | |||
if (is_start) { | |||
pes->state = MPEGTS_HEADER; | |||
@@ -722,59 +784,7 @@ static void mpegts_push_data(void *opaque, | |||
goto skip; | |||
if (!pes->st) { | |||
/* allocate stream */ | |||
switch(pes->stream_type){ | |||
case STREAM_TYPE_AUDIO_MPEG1: | |||
case STREAM_TYPE_AUDIO_MPEG2: | |||
codec_type = CODEC_TYPE_AUDIO; | |||
codec_id = CODEC_ID_MP3; | |||
break; | |||
case STREAM_TYPE_VIDEO_MPEG1: | |||
case STREAM_TYPE_VIDEO_MPEG2: | |||
codec_type = CODEC_TYPE_VIDEO; | |||
codec_id = CODEC_ID_MPEG2VIDEO; | |||
break; | |||
case STREAM_TYPE_VIDEO_MPEG4: | |||
codec_type = CODEC_TYPE_VIDEO; | |||
codec_id = CODEC_ID_MPEG4; | |||
break; | |||
case STREAM_TYPE_VIDEO_H264: | |||
codec_type = CODEC_TYPE_VIDEO; | |||
codec_id = CODEC_ID_H264; | |||
break; | |||
case STREAM_TYPE_AUDIO_AAC: | |||
codec_type = CODEC_TYPE_AUDIO; | |||
codec_id = CODEC_ID_AAC; | |||
break; | |||
case STREAM_TYPE_AUDIO_AC3: | |||
codec_type = CODEC_TYPE_AUDIO; | |||
codec_id = CODEC_ID_AC3; | |||
break; | |||
case STREAM_TYPE_AUDIO_DTS: | |||
codec_type = CODEC_TYPE_AUDIO; | |||
codec_id = CODEC_ID_DTS; | |||
break; | |||
default: | |||
if (code >= 0x1c0 && code <= 0x1df) { | |||
codec_type = CODEC_TYPE_AUDIO; | |||
codec_id = CODEC_ID_MP2; | |||
} else if (code == 0x1bd) { | |||
codec_type = CODEC_TYPE_AUDIO; | |||
codec_id = CODEC_ID_AC3; | |||
} else { | |||
codec_type = CODEC_TYPE_VIDEO; | |||
codec_id = CODEC_ID_MPEG1VIDEO; | |||
} | |||
break; | |||
} | |||
st = av_new_stream(pes->stream, pes->pid); | |||
if (st) { | |||
av_set_pts_info(st, 33, 1, 90000); | |||
st->priv_data = pes; | |||
st->codec.codec_type = codec_type; | |||
st->codec.codec_id = codec_id; | |||
st->need_parsing = 1; | |||
pes->st = st; | |||
} | |||
new_pes_av_stream(pes, code); | |||
} | |||
pes->state = MPEGTS_PESHEADER_FILL; | |||
pes->total_size = (pes->header[4] << 8) | pes->header[5]; | |||
@@ -854,7 +864,73 @@ static void mpegts_push_data(void *opaque, | |||
} | |||
} | |||
static int add_pes_stream(MpegTSContext *ts, int pid, int stream_type) | |||
static AVStream* new_pes_av_stream(PESContext *pes, uint32_t code) | |||
{ | |||
AVStream *st; | |||
int codec_type, codec_id; | |||
switch(pes->stream_type){ | |||
case STREAM_TYPE_AUDIO_MPEG1: | |||
case STREAM_TYPE_AUDIO_MPEG2: | |||
codec_type = CODEC_TYPE_AUDIO; | |||
codec_id = CODEC_ID_MP3; | |||
break; | |||
case STREAM_TYPE_VIDEO_MPEG1: | |||
case STREAM_TYPE_VIDEO_MPEG2: | |||
codec_type = CODEC_TYPE_VIDEO; | |||
codec_id = CODEC_ID_MPEG2VIDEO; | |||
break; | |||
case STREAM_TYPE_VIDEO_MPEG4: | |||
codec_type = CODEC_TYPE_VIDEO; | |||
codec_id = CODEC_ID_MPEG4; | |||
break; | |||
case STREAM_TYPE_VIDEO_H264: | |||
codec_type = CODEC_TYPE_VIDEO; | |||
codec_id = CODEC_ID_H264; | |||
break; | |||
case STREAM_TYPE_AUDIO_AAC: | |||
codec_type = CODEC_TYPE_AUDIO; | |||
codec_id = CODEC_ID_AAC; | |||
break; | |||
case STREAM_TYPE_AUDIO_AC3: | |||
codec_type = CODEC_TYPE_AUDIO; | |||
codec_id = CODEC_ID_AC3; | |||
break; | |||
case STREAM_TYPE_AUDIO_DTS: | |||
codec_type = CODEC_TYPE_AUDIO; | |||
codec_id = CODEC_ID_DTS; | |||
break; | |||
case STREAM_TYPE_SUBTITLE_DVB: | |||
codec_type = CODEC_TYPE_SUBTITLE; | |||
codec_id = CODEC_ID_DVB_SUBTITLE; | |||
break; | |||
default: | |||
if (code >= 0x1c0 && code <= 0x1df) { | |||
codec_type = CODEC_TYPE_AUDIO; | |||
codec_id = CODEC_ID_MP2; | |||
} else if (code == 0x1bd) { | |||
codec_type = CODEC_TYPE_AUDIO; | |||
codec_id = CODEC_ID_AC3; | |||
} else { | |||
codec_type = CODEC_TYPE_VIDEO; | |||
codec_id = CODEC_ID_MPEG1VIDEO; | |||
} | |||
break; | |||
} | |||
st = av_new_stream(pes->stream, pes->pid); | |||
if (st) { | |||
av_set_pts_info(st, 33, 1, 90000); | |||
st->priv_data = pes; | |||
st->codec.codec_type = codec_type; | |||
st->codec.codec_id = codec_id; | |||
st->need_parsing = 1; | |||
pes->st = st; | |||
} | |||
return st; | |||
} | |||
static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int stream_type) | |||
{ | |||
MpegTSFilter *tss; | |||
PESContext *pes; | |||
@@ -862,7 +938,7 @@ static int add_pes_stream(MpegTSContext *ts, int pid, int stream_type) | |||
/* if no pid found, then add a pid context */ | |||
pes = av_mallocz(sizeof(PESContext)); | |||
if (!pes) | |||
return -1; | |||
return 0; | |||
pes->ts = ts; | |||
pes->stream = ts->stream; | |||
pes->pid = pid; | |||
@@ -870,9 +946,9 @@ static int add_pes_stream(MpegTSContext *ts, int pid, int stream_type) | |||
tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes); | |||
if (!tss) { | |||
av_free(pes); | |||
return -1; | |||
return 0; | |||
} | |||
return 0; | |||
return pes; | |||
} | |||
/* handle one TS packet */ | |||
@@ -1131,11 +1207,11 @@ static int mpegts_read_header(AVFormatContext *s, | |||
} | |||
if (ts->nb_services <= 0) { | |||
/* raw transport stream */ | |||
ts->auto_guess = 1; | |||
s->ctx_flags |= AVFMTCTX_NOHEADER; | |||
goto do_pcr; | |||
} | |||
/* raw transport stream */ | |||
ts->auto_guess = 1; | |||
s->ctx_flags |= AVFMTCTX_NOHEADER; | |||
goto do_pcr; | |||
} | |||
/* tune to first service found */ | |||
for(i=0; i<ts->nb_services && ts->set_service_ret; i++){ | |||
@@ -31,6 +31,9 @@ | |||
#define PMT_TID 0x02 | |||
#define SDT_TID 0x42 | |||
/* descriptor ids */ | |||
#define DVB_SUBT_DESCID 0x59 | |||
#define STREAM_TYPE_VIDEO_MPEG1 0x01 | |||
#define STREAM_TYPE_VIDEO_MPEG2 0x02 | |||
#define STREAM_TYPE_AUDIO_MPEG1 0x03 | |||
@@ -44,6 +47,8 @@ | |||
#define STREAM_TYPE_AUDIO_AC3 0x81 | |||
#define STREAM_TYPE_AUDIO_DTS 0x8a | |||
#define STREAM_TYPE_SUBTITLE_DVB 0x100 | |||
unsigned int mpegts_crc32(const uint8_t *data, int len); | |||
extern AVOutputFormat mpegts_mux; | |||
@@ -2508,6 +2508,9 @@ void dump_format(AVFormatContext *ic, | |||
if (flags & AVFMT_SHOW_IDS) { | |||
av_log(NULL, AV_LOG_INFO, "[0x%x]", st->id); | |||
} | |||
if (strlen(st->language) > 0) { | |||
av_log(NULL, AV_LOG_INFO, "(%s)", st->language); | |||
} | |||
av_log(NULL, AV_LOG_INFO, ": %s\n", buf); | |||
} | |||
} | |||