static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { FRWUContext *s = avctx->priv_data; int field, ret; AVFrame *pic = data; const uint8_t *buf = avpkt->data; const uint8_t *buf_end = buf + avpkt->size; if (avpkt->size < avctx->width * 2 * avctx->height + 4 + 2*8) { av_log(avctx, AV_LOG_ERROR, "Packet is too small.\n"); return AVERROR_INVALIDDATA; } if (bytestream_get_le32(&buf) != MKTAG('F', 'R', 'W', '1')) { av_log(avctx, AV_LOG_ERROR, "incorrect marker\n"); return AVERROR_INVALIDDATA; } if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; pic->pict_type = AV_PICTURE_TYPE_I; pic->key_frame = 1; for (field = 0; field < 2; field++) { int i; int field_h = (avctx->height + !field) >> 1; int field_size, min_field_size = avctx->width * 2 * field_h; uint8_t *dst = pic->data[0]; if (buf_end - buf < 8) return AVERROR_INVALIDDATA; buf += 4; // flags? 0x80 == bottom field maybe? field_size = bytestream_get_le32(&buf); if (field_size < min_field_size) { av_log(avctx, AV_LOG_ERROR, "Field size %i is too small (required %i)\n", field_size, min_field_size); return AVERROR_INVALIDDATA; } if (buf_end - buf < field_size) { av_log(avctx, AV_LOG_ERROR, "Packet is too small, need %i, have %i\n", field_size, (int)(buf_end - buf)); return AVERROR_INVALIDDATA; } if (field ^ s->change_field_order) { dst += pic->linesize[0]; } else if (s->change_field_order) { dst += 2 * pic->linesize[0]; } for (i = 0; i < field_h; i++) { if (s->change_field_order && field && i == field_h - 1) dst = pic->data[0]; memcpy(dst, buf, avctx->width * 2); buf += avctx->width * 2; dst += pic->linesize[0] << 1; } buf += field_size - min_field_size; } *got_frame = 1; return avpkt->size; }
static int msnwc_tcp_probe(AVProbeData *p) { int i; for(i = 0 ; i + HEADER_SIZE <= p->buf_size ; i++) { uint16_t width, height; uint32_t fourcc; const uint8_t *bytestream = p->buf+i; if(bytestream_get_le16(&bytestream) != HEADER_SIZE) continue; width = bytestream_get_le16(&bytestream); height = bytestream_get_le16(&bytestream); if(!(width==320 && height==240) && !(width==160 && height==120)) continue; bytestream += 2; // keyframe bytestream += 4; // size fourcc = bytestream_get_le32(&bytestream); if(fourcc != MKTAG('M', 'L', '2', '0')) continue; if(i) { if(i < 14) /* starts with SwitchBoard connection info */ return AVPROBE_SCORE_MAX / 2; else /* starts in the middle of stream */ return AVPROBE_SCORE_MAX / 3; } else { return AVPROBE_SCORE_MAX; } } return -1; }
static av_cold int decode_init(AVCodecContext *avctx) { AnmContext *s = avctx->priv_data; const uint8_t *buf; int i; avctx->pix_fmt = PIX_FMT_PAL8; if (avctx->extradata_size != 16*8 + 4*256) return -1; s->frame.reference = 1; buf = avctx->extradata + 16*8; for (i = 0; i < 256; i++) s->palette[i] = bytestream_get_le32(&buf); return 0; }
static int mimic_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { MimicContext *ctx = avctx->priv_data; int is_pframe; int width, height; int quality, num_coeffs; int swap_buf_size = buf_size - MIMIC_HEADER_SIZE; if(buf_size < MIMIC_HEADER_SIZE) { av_log(avctx, AV_LOG_ERROR, "insufficient data\n"); return -1; } buf += 2; /* some constant (always 256) */ quality = bytestream_get_le16(&buf); width = bytestream_get_le16(&buf); height = bytestream_get_le16(&buf); buf += 4; /* some constant */ is_pframe = bytestream_get_le32(&buf); num_coeffs = bytestream_get_byte(&buf); buf += 3; /* some constant */ if(!ctx->avctx) { int i; if(!(width == 160 && height == 120) && !(width == 320 && height == 240)) { av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n"); return -1; } ctx->avctx = avctx; avctx->width = width; avctx->height = height; avctx->pix_fmt = PIX_FMT_YUV420P; for(i = 0; i < 3; i++) { ctx->num_vblocks[i] = -((-height) >> (3 + !!i)); ctx->num_hblocks[i] = width >> (3 + !!i) ; } } else if(width != ctx->avctx->width || height != ctx->avctx->height) {
static av_cold int decode_init(AVCodecContext *avctx) { AnmContext *s = avctx->priv_data; const uint8_t *buf; int i; avctx->pix_fmt = PIX_FMT_PAL8; if (avctx->extradata_size != 16*8 + 4*256) return -1; s->frame.reference = 1; if (avctx->get_buffer(avctx, &s->frame) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } buf = avctx->extradata + 16*8; for (i = 0; i < 256; i++) ((uint32_t*)s->frame.data[1])[i] = bytestream_get_le32(&buf); return 0; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { int field, ret; AVFrame *pic = avctx->coded_frame; const uint8_t *buf = avpkt->data; const uint8_t *buf_end = buf + avpkt->size; if (pic->data[0]) avctx->release_buffer(avctx, pic); if (avpkt->size < avctx->width * 2 * avctx->height + 4 + 2*8) { av_log(avctx, AV_LOG_ERROR, "Packet is too small.\n"); return AVERROR_INVALIDDATA; } if (bytestream_get_le32(&buf) != AV_RL32("FRW1")) { av_log(avctx, AV_LOG_ERROR, "incorrect marker\n"); return AVERROR_INVALIDDATA; } pic->reference = 0; if ((ret = avctx->get_buffer(avctx, pic)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } pic->pict_type = AV_PICTURE_TYPE_I; pic->key_frame = 1; pic->interlaced_frame = 1; pic->top_field_first = 1; for (field = 0; field < 2; field++) { int i; int field_h = (avctx->height + !field) >> 1; int field_size, min_field_size = avctx->width * 2 * field_h; uint8_t *dst = pic->data[0]; if (buf_end - buf < 8) return AVERROR_INVALIDDATA; buf += 4; // flags? 0x80 == bottom field maybe? field_size = bytestream_get_le32(&buf); if (field_size < min_field_size) { av_log(avctx, AV_LOG_ERROR, "Field size %i is too small (required %i)\n", field_size, min_field_size); return AVERROR_INVALIDDATA; } if (buf_end - buf < field_size) { av_log(avctx, AV_LOG_ERROR, "Packet is too small, need %i, have %i\n", field_size, (int)(buf_end - buf)); return AVERROR_INVALIDDATA; } if (field) dst += pic->linesize[0]; for (i = 0; i < field_h; i++) { memcpy(dst, buf, avctx->width * 2); buf += avctx->width * 2; dst += pic->linesize[0] << 1; } buf += field_size - min_field_size; } *data_size = sizeof(AVFrame); *(AVFrame*)data = *pic; return avpkt->size; }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; C93DecoderContext * const c93 = avctx->priv_data; AVFrame * const newpic = &c93->pictures[c93->currentpic]; AVFrame * const oldpic = &c93->pictures[c93->currentpic^1]; AVFrame *picture = data; uint8_t *out; int stride, i, x, y, bt = 0; c93->currentpic ^= 1; newpic->reference = 1; newpic->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE; if (avctx->reget_buffer(avctx, newpic)) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return -1; } stride = newpic->linesize[0]; if (buf[0] & C93_FIRST_FRAME) { newpic->pict_type = FF_I_TYPE; newpic->key_frame = 1; } else { newpic->pict_type = FF_P_TYPE; newpic->key_frame = 0; } if (*buf++ & C93_HAS_PALETTE) { uint32_t *palette = (uint32_t *) newpic->data[1]; const uint8_t *palbuf = buf + buf_size - 768 - 1; for (i = 0; i < 256; i++) { palette[i] = bytestream_get_be24(&palbuf); } } else { if (oldpic->data[1]) memcpy(newpic->data[1], oldpic->data[1], 256 * 4); } for (y = 0; y < HEIGHT; y += 8) { out = newpic->data[0] + y * stride; for (x = 0; x < WIDTH; x += 8) { uint8_t *copy_from = oldpic->data[0]; unsigned int offset, j; uint8_t cols[4], grps[4]; C93BlockType block_type; if (!bt) bt = *buf++; block_type= bt & 0x0F; switch (block_type) { case C93_8X8_FROM_PREV: offset = bytestream_get_le16(&buf); if (copy_block(avctx, out, copy_from, offset, 8, stride)) return -1; break; case C93_4X4_FROM_CURR: copy_from = newpic->data[0]; case C93_4X4_FROM_PREV: for (j = 0; j < 8; j += 4) { for (i = 0; i < 8; i += 4) { offset = bytestream_get_le16(&buf); if (copy_block(avctx, &out[j*stride+i], copy_from, offset, 4, stride)) return -1; } } break; case C93_8X8_2COLOR: bytestream_get_buffer(&buf, cols, 2); for (i = 0; i < 8; i++) { draw_n_color(out + i*stride, stride, 8, 1, 1, cols, NULL, *buf++); } break; case C93_4X4_2COLOR: case C93_4X4_4COLOR: case C93_4X4_4COLOR_GRP: for (j = 0; j < 8; j += 4) { for (i = 0; i < 8; i += 4) { if (block_type == C93_4X4_2COLOR) { bytestream_get_buffer(&buf, cols, 2); draw_n_color(out + i + j*stride, stride, 4, 4, 1, cols, NULL, bytestream_get_le16(&buf)); } else if (block_type == C93_4X4_4COLOR) { bytestream_get_buffer(&buf, cols, 4); draw_n_color(out + i + j*stride, stride, 4, 4, 2, cols, NULL, bytestream_get_le32(&buf)); } else { bytestream_get_buffer(&buf, grps, 4); draw_n_color(out + i + j*stride, stride, 4, 4, 1, cols, grps, bytestream_get_le16(&buf)); } } } break; case C93_NOOP: break; case C93_8X8_INTRA: for (j = 0; j < 8; j++) bytestream_get_buffer(&buf, out + j*stride, 8); break; default: av_log(avctx, AV_LOG_ERROR, "unexpected type %x at %dx%d\n", block_type, x, y); return -1; } bt >>= 4; out += 8; } } *picture = *newpic; *data_size = sizeof(AVFrame); return buf_size; }
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 apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) { int size = 0, ret; const uint8_t *data; uint32_t flags; data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); if (!data) return 0; if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) { av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " "changes, but PARAM_CHANGE side data was sent to it.\n"); ret = AVERROR(EINVAL); goto fail2; } if (size < 4) goto fail; flags = bytestream_get_le32(&data); size -= 4; if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) { if (size < 4) goto fail; avctx->channels = bytestream_get_le32(&data); size -= 4; } if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { if (size < 8) goto fail; avctx->channel_layout = bytestream_get_le64(&data); size -= 8; } if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { if (size < 4) goto fail; avctx->sample_rate = bytestream_get_le32(&data); size -= 4; } if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { if (size < 8) goto fail; avctx->width = bytestream_get_le32(&data); avctx->height = bytestream_get_le32(&data); size -= 8; ret = ff_set_dimensions(avctx, avctx->width, avctx->height); if (ret < 0) goto fail2; } return 0; fail: av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); ret = AVERROR_INVALIDDATA; fail2: if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); if (avctx->err_recognition & AV_EF_EXPLODE) return ret; } return 0; }
/* Decoder for mpff format. Copies data from the passed in *AVPacket to the data pointer argument */ static int mpff_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { //Pointer to the av packet's data const uint8_t *buf = avpkt->data; //The size of the buffer is the size of the avpacket int buf_size = avpkt->size; //Sets up a AVFrame pointer to the data pointer AVFrame *p = data; int width, height, linesize, ret; int i, j; //byte toadd; uint8_t *ptr, *ptr0; //Conditional statement checks that the header file indicates //mpff format if (bytestream_get_byte(&buf) != 'M' ||bytestream_get_byte(&buf) != 'P' ||bytestream_get_byte(&buf) != 'F' ||bytestream_get_byte(&buf) != 'F') { av_log(avctx, AV_LOG_ERROR, "bad magic number\n"); return AVERROR_INVALIDDATA; } //Get the width out of the buffer width = bytestream_get_le32(&buf); //Get the height out of the buffer height = bytestream_get_le32(&buf); //set up the av context avctx->width = width; avctx->height = height; //RGB8 is the only pixel fmt supported (see structure) avctx->pix_fmt = AV_PIX_FMT_RGB8; //Set up av context if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; //ptr is the frame's data and the line size is just //the size of the frame ptr = p->data[0]; ptr0 = ptr; linesize = p->linesize[0]; //Loop over each line of the image for (i = 0; i < avctx->height; i++) { for (j = 0; j < avctx->width; j++) { //Copy the bits from ptr to the buffer //advance the buffer and ptr pointers bytestream_put_byte(&ptr, bytestream_get_byte(&buf)); } ptr = ptr0 + linesize; ptr0 = ptr; /* //copy the bits from the buffer to ptr memcpy(ptr, buf, width); //Move the buffer and ptr pointer up buf += linesize; //width; ptr += linesize; */ } *got_frame = 1; return buf_size; }
// decodes the frame static int utah_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { UTAHContext *context = avctx->priv_data; const uint8_t *buffer = avpkt->data; uint8_t* pic_buffer; int buffer_size = avpkt->size; int height = 0; int width = 0; int ret; int hsize = 14; int line = 0; int n_bytes = 0; AVFrame *picture = data; AVFrame *pic = &context->picture; avctx->pix_fmt = AV_PIX_FMT_RGB24; // ensure the image has the correct header size if(buffer_size < hsize) { av_log(avctx, AV_LOG_ERROR, "Image is not a .utah image(invalid hsize size)\n"); return AVERROR_INVALIDDATA; } // ensure the image is a utah image if(bytestream_get_byte(&buffer) != 'U' || bytestream_get_byte(&buffer)!='T') { av_log(avctx, AV_LOG_ERROR, "Invalid .utah image\n"); return AVERROR_INVALIDDATA; } height = bytestream_get_le32(&buffer);// Get the height from the packet buffer width = bytestream_get_le32(&buffer);// get the width from the packet buffer avctx->height = height; line = bytestream_get_le32(&buffer); avctx->width =width; // get the number of bytes n_bytes = height*line + hsize; if(n_bytes != buffer_size) { av_log(avctx, AV_LOG_ERROR, "Invalid image size"); return AVERROR_INVALIDDATA; } if (pic->data[0]) { avctx->release_buffer(avctx, pic); } pic->reference = 0; if ((ret = ff_get_buffer(avctx, pic)) < 0) { return ret; } memset(pic->data[0], 0, height*pic->linesize[0]); pic_buffer = pic->data[0]; for(int row = 0; row<fheight;row++) { memcpy(pic_buffer, buffer, line); pic_buffer += pic->linesize[0]; buffer += line; } *picture = context->picture; *got_frame = 1; return buffer_size; }
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); }