static void metadata_conv(AVMetadata **pm, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv) { /* TODO: use binary search to look up the two conversion tables if the tables are getting big enough that it would matter speed wise */ const AVMetadataConv *sc, *dc; AVMetadataTag *mtag = NULL; AVMetadata *dst = NULL; const char *key; while((mtag=av_metadata_get(*pm, "", mtag, AV_METADATA_IGNORE_SUFFIX))) { key = mtag->key; if (s_conv != d_conv) { if (s_conv) for (sc=s_conv; sc->native; sc++) if (!strcasecmp(key, sc->native)) { key = sc->generic; break; } if (d_conv) for (dc=d_conv; dc->native; dc++) if (!strcasecmp(key, dc->generic)) { key = dc->native; break; } } av_metadata_set(&dst, key, mtag->value); } av_metadata_free(pm); *pm = dst; }
static int r3d_read_red1(AVFormatContext *s) { AVStream *st = av_new_stream(s, 0); char filename[258]; int tmp, tmp2; if (!st) return AVERROR(ENOMEM); st->codec->codec_type = CODEC_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_JPEG2000; tmp = get_byte(s->pb); // major version tmp2 = get_byte(s->pb); // minor version dprintf(s, "version %d.%d\n", tmp, tmp2); tmp = get_be16(s->pb); // unknown dprintf(s, "unknown1 %d\n", tmp); tmp = get_be32(s->pb); av_set_pts_info(st, 32, 1, tmp); tmp = get_be32(s->pb); // filenum dprintf(s, "filenum %d\n", tmp); url_fskip(s->pb, 32); // unknown st->codec->width = get_be32(s->pb); st->codec->height = get_be32(s->pb); tmp = get_be16(s->pb); // unknown dprintf(s, "unknown2 %d\n", tmp); st->codec->time_base.den = get_be16(s->pb); st->codec->time_base.num = get_be16(s->pb); tmp = get_byte(s->pb); // audio channels dprintf(s, "audio channels %d\n", tmp); if (tmp > 0) { AVStream *ast = av_new_stream(s, 1); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = CODEC_TYPE_AUDIO; ast->codec->codec_id = CODEC_ID_PCM_S32BE; ast->codec->channels = tmp; av_set_pts_info(ast, 32, 1, st->time_base.den); } get_buffer(s->pb, filename, 257); filename[sizeof(filename)-1] = 0; av_metadata_set(&st->metadata, "filename", filename); dprintf(s, "filename %s\n", filename); dprintf(s, "resolution %dx%d\n", st->codec->width, st->codec->height); dprintf(s, "timescale %d\n", st->time_base.den); dprintf(s, "frame rate %d/%d\n", st->codec->time_base.num, st->codec->time_base.den); return 0; }
/** Read information chunk */ static void read_info_chunk(AVFormatContext *s, int64_t size) { ByteIOContext *pb = s->pb; unsigned int i; unsigned int nb_entries = get_be32(pb); for (i = 0; i < nb_entries; i++) { char key[32]; char value[1024]; get_strz(pb, key, sizeof(key)); get_strz(pb, value, sizeof(value)); av_metadata_set(&s->metadata, key, value); } }
/* Metadata string read */ static void get_meta(AVFormatContext *s, const char *key, int size) { uint8_t str[1024]; int res = get_buffer(s->pb, str, FFMIN(sizeof(str)-1, size)); if (res < 0) return; str[res] = 0; if (size & 1) size++; size -= res; if (size) url_fskip(s->pb, size); av_metadata_set(&s->metadata, key, str); }
static void ape_tag_read_field(AVFormatContext *s) { ByteIOContext *pb = s->pb; uint8_t key[1024], value[1024]; uint32_t size; int i, l; size = get_le32(pb); /* field size */ url_fskip(pb, 4); /* skip field flags */ for (i=0; pb->buf_ptr[i]!='0' && pb->buf_ptr[i]>=0x20 && pb->buf_ptr[i]<=0x7E; i++); l = FFMIN(i, sizeof(key) -1); get_buffer(pb, key, l); key[l] = 0; url_fskip(pb, 1 + i-l); l = FFMIN(size, sizeof(value)-1); get_buffer(pb, value, l); value[l] = 0; url_fskip(pb, size-l); if (l < size) av_log(s, AV_LOG_WARNING, "Too long '%s' tag was truncated.\n", key); av_metadata_set(&s->metadata, key, value); }
static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { MpegTSContext *ts = filter->u.section_filter.opaque; SectionHeader h1, *h = &h1; const uint8_t *p, *p_end, *desc_list_end, *desc_end; int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type; char *name, *provider_name; #ifdef DEBUG dprintf(ts->stream, "SDT:\n"); av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); #endif p_end = section + section_len - 4; p = section; if (parse_section_header(h, &p, p_end) < 0) return; if (h->tid != SDT_TID) return; onid = get16(&p, p_end); if (onid < 0) return; val = get8(&p, p_end); if (val < 0) return; for(;;) { sid = get16(&p, p_end); if (sid < 0) break; val = get8(&p, p_end); if (val < 0) break; 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; 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; dprintf(ts->stream, "tag: 0x%02x len=%d\n", desc_tag, desc_len); switch(desc_tag) { case 0x48: service_type = get8(&p, p_end); if (service_type < 0) break; provider_name = getstr8(&p, p_end); if (!provider_name) break; name = getstr8(&p, p_end); if (name) { AVProgram *program = av_new_program(ts->stream, sid); if(program) { av_metadata_set(&program->metadata, "name", name); av_metadata_set(&program->metadata, "provider_name", provider_name); } } av_free(name); av_free(provider_name); break; default: break; } p = desc_end; } p = desc_list_end; } }
static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { MpegTSContext *ts = filter->u.section_filter.opaque; SectionHeader h1, *h = &h1; 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 = 0, anc_page = 0; /* initialize to kill warnings */ char language[4] = {0}; /* initialize to kill warnings */ int has_hdmv_descr = 0; int has_dirac_descr = 0; uint32_t reg_desc = 0; /* registration descriptor */ #ifdef DEBUG dprintf(ts->stream, "PMT: len %i\n", section_len); av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); #endif p_end = section + section_len - 4; p = section; if (parse_section_header(h, &p, p_end) < 0) return; dprintf(ts->stream, "sid=0x%x sec_num=%d/%d\n", h->id, h->sec_num, h->last_sec_num); if (h->tid != PMT_TID) return; clear_program(ts, h->id); pcr_pid = get16(&p, p_end) & 0x1fff; if (pcr_pid < 0) return; add_pid_to_pmt(ts, h->id, pcr_pid); dprintf(ts->stream, "pcr_pid=0x%x\n", pcr_pid); program_info_length = get16(&p, p_end) & 0xfff; if (program_info_length < 0) return; while(program_info_length >= 2) { uint8_t tag, len; tag = get8(&p, p_end); len = get8(&p, p_end); if(len > program_info_length - 2) //something else is broken, exit the program_descriptors_loop break; program_info_length -= len + 2; if(tag == REGISTRATION_DESCRIPTOR && len >= 4) { reg_desc = bytestream_get_le32(&p); len -= 4; if(reg_desc == AV_RL32("HDMV")) has_hdmv_descr = 1; } p += len; } p += program_info_length; 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_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; for(;;) { desc_tag = get8(&p, desc_list_end); if (desc_tag < 0) break; if (stream_type == STREAM_TYPE_PRIVATE_DATA) { if((desc_tag == 0x6A) || (desc_tag == 0x7A)) { /*assume DVB AC-3 Audio*/ stream_type = STREAM_TYPE_AUDIO_AC3; } else if(desc_tag == 0x7B) { /* DVB DTS audio */ stream_type = STREAM_TYPE_AUDIO_DTS; } } desc_len = get8(&p, desc_list_end); if (desc_len < 0) break; desc_end = p + desc_len; if (desc_end > desc_list_end) break; dprintf(ts->stream, "tag: 0x%02x len=%d\n", desc_tag, desc_len); 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; case REGISTRATION_DESCRIPTOR: /*MPEG-2 Registration descriptor */ reg_desc = bytestream_get_le32(&p); if(reg_desc == AV_RL32("drac")) has_dirac_descr = 1; else if(reg_desc == AV_RL32("AC-3")) stream_type = STREAM_TYPE_AUDIO_AC3; break; default: break; } p = desc_end; } p = desc_list_end; dprintf(ts->stream, "stream_type=%x pid=0x%x\n", stream_type, pid); /* now create ffmpeg stream */ switch(stream_type) { case STREAM_TYPE_AUDIO_MPEG1: case STREAM_TYPE_AUDIO_MPEG2: case STREAM_TYPE_VIDEO_MPEG1: case STREAM_TYPE_VIDEO_MPEG2: case STREAM_TYPE_VIDEO_MPEG4: case STREAM_TYPE_VIDEO_H264: case STREAM_TYPE_VIDEO_VC1: case STREAM_TYPE_VIDEO_DIRAC: case STREAM_TYPE_AUDIO_AAC: case STREAM_TYPE_AUDIO_AC3: case STREAM_TYPE_AUDIO_DTS: case STREAM_TYPE_AUDIO_HDMV_DTS: case STREAM_TYPE_SUBTITLE_DVB: if((stream_type == STREAM_TYPE_AUDIO_HDMV_DTS && !has_hdmv_descr) || (stream_type == STREAM_TYPE_VIDEO_DIRAC && !has_dirac_descr)) break; if(ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES){ pes= ts->pids[pid]->u.pes_filter.opaque; st= pes->st; }else{ if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably pes = add_pes_stream(ts, pid, pcr_pid, stream_type); if (pes) st = new_pes_av_stream(pes, 0); } add_pid_to_pmt(ts, h->id, pid); if(st) av_program_add_stream_index(ts->stream, h->id, st->index); break; default: /* we ignore the other streams */ break; } if (st) { if (language[0] != 0) { av_metadata_set(&st->metadata, "language", language); } if (stream_type == STREAM_TYPE_SUBTITLE_DVB) { st->codec->sub_id = (anc_page << 16) | comp_page; } } } /* all parameters are there */ ts->stop_parse++; mpegts_close_filter(ts, filter); }
static int sox_read_header(AVFormatContext *s, AVFormatParameters *ap) { ByteIOContext *pb = s->pb; unsigned header_size, comment_size; double sample_rate, sample_rate_frac; AVStream *st; st = av_new_stream(s, 0); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = CODEC_TYPE_AUDIO; if (get_le32(pb) == SOX_TAG) { st->codec->codec_id = CODEC_ID_PCM_S32LE; header_size = get_le32(pb); url_fskip(pb, 8); /* sample count */ sample_rate = av_int2dbl(get_le64(pb)); st->codec->channels = get_le32(pb); comment_size = get_le32(pb); } else { st->codec->codec_id = CODEC_ID_PCM_S32BE; header_size = get_be32(pb); url_fskip(pb, 8); /* sample count */ sample_rate = av_int2dbl(get_be64(pb)); st->codec->channels = get_be32(pb); comment_size = get_be32(pb); } if (comment_size > 0xFFFFFFFFU - SOX_FIXED_HDR - 4U) { av_log(s, AV_LOG_ERROR, "invalid comment size (%u)\n", comment_size); return -1; } if (sample_rate <= 0 || sample_rate > INT_MAX) { av_log(s, AV_LOG_ERROR, "invalid sample rate (%f)\n", sample_rate); return -1; } sample_rate_frac = sample_rate - floor(sample_rate); if (sample_rate_frac) av_log(s, AV_LOG_WARNING, "truncating fractional part of sample rate (%f)\n", sample_rate_frac); if ((header_size + 4) & 7 || header_size < SOX_FIXED_HDR + comment_size || st->codec->channels > 65535) /* Reserve top 16 bits */ { av_log(s, AV_LOG_ERROR, "invalid header\n"); return -1; } if (comment_size && comment_size + FF_INPUT_BUFFER_PADDING_SIZE >= comment_size) { char *comment = av_mallocz(comment_size + FF_INPUT_BUFFER_PADDING_SIZE); if (get_buffer(pb, comment, comment_size) != comment_size) { av_freep(&comment); return AVERROR_IO; } av_metadata_set(&s->metadata, "comment", comment); av_freep(&comment); } url_fskip(pb, header_size - SOX_FIXED_HDR - comment_size); st->codec->sample_rate = sample_rate; st->codec->bits_per_coded_sample = 32; st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample * st->codec->channels; st->codec->block_align = st->codec->bits_per_coded_sample * st->codec->channels / 8; av_set_pts_info(st, 64, 1, st->codec->sample_rate); return 0; }
static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { MpegTSContext *ts = filter->u.section_filter.opaque; SectionHeader h1, *h = &h1; 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]; uint32_t prog_reg_desc = 0; /* registration descriptor */ #ifdef DEBUG dprintf(ts->stream, "PMT: len %i\n", section_len); av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len); #endif p_end = section + section_len - 4; p = section; if (parse_section_header(h, &p, p_end) < 0) return; dprintf(ts->stream, "sid=0x%x sec_num=%d/%d\n", h->id, h->sec_num, h->last_sec_num); if (h->tid != PMT_TID) return; clear_program(ts, h->id); pcr_pid = get16(&p, p_end) & 0x1fff; if (pcr_pid < 0) return; add_pid_to_pmt(ts, h->id, pcr_pid); dprintf(ts->stream, "pcr_pid=0x%x\n", pcr_pid); program_info_length = get16(&p, p_end) & 0xfff; if (program_info_length < 0) return; while(program_info_length >= 2) { uint8_t tag, len; tag = get8(&p, p_end); len = get8(&p, p_end); if(len > program_info_length - 2) //something else is broken, exit the program_descriptors_loop break; program_info_length -= len + 2; if(tag == 0x05 && len >= 4) { // registration descriptor prog_reg_desc = bytestream_get_le32(&p); len -= 4; } p += len; } p += program_info_length; if (p >= p_end) return; for(;;) { st = 0; stream_type = get8(&p, p_end); if (stream_type < 0) break; pid = get16(&p, p_end) & 0x1fff; if (pid < 0) break; /* now create ffmpeg stream */ if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) { pes = ts->pids[pid]->u.pes_filter.opaque; st = pes->st; } else { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably pes = add_pes_stream(ts, pid, pcr_pid, stream_type); if (pes) st = new_pes_av_stream(pes, prog_reg_desc, 0); } if (!st) return; add_pid_to_pmt(ts, h->id, pid); av_program_add_stream_index(ts->stream, h->id, st->index); 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; for(;;) { desc_tag = get8(&p, desc_list_end); if (desc_tag < 0) break; desc_len = get8(&p, desc_list_end); if (desc_len < 0) break; desc_end = p + desc_len; if (desc_end > desc_list_end) break; dprintf(ts->stream, "tag: 0x%02x len=%d\n", desc_tag, desc_len); if (st->codec->codec_id == CODEC_ID_PROBE && stream_type == STREAM_TYPE_PRIVATE_DATA) mpegts_find_stream_type(st, desc_tag, DESC_types); switch(desc_tag) { case 0x59: /* subtitling descriptor */ 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); st->codec->sub_id = (anc_page << 16) | comp_page; av_metadata_set(&st->metadata, "language", language); 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; av_metadata_set(&st->metadata, "language", language); break; case 0x05: /* registration descriptor */ st->codec->codec_tag = bytestream_get_le32(&p); dprintf(ts->stream, "reg_desc=%.4s\n", (char*)&st->codec->codec_tag); if (st->codec->codec_id == CODEC_ID_PROBE && stream_type == STREAM_TYPE_PRIVATE_DATA) mpegts_find_stream_type(st, st->codec->codec_tag, REGD_types); break; default: break; } p = desc_end; } p = desc_list_end; } /* all parameters are there */ ts->stop_parse++; mpegts_close_filter(ts, filter); }