void xtr_hevc_c::create_file(xtr_base_c *master, KaxTrackEntry &track) { xtr_base_c::create_file(master, track); auto priv = FindChild<KaxCodecPrivate>(&track); if (!priv) mxerror(boost::format(Y("Track %1% with the CodecID '%2%' is missing the \"codec private\" element and cannot be extracted.\n")) % m_tid % m_codec_id); auto mpriv = decode_codec_private(priv); if (mpriv->get_size() < 23) mxerror(boost::format(Y("Track %1% CodecPrivate is too small.\n")) % m_tid); auto buf = mpriv->get_buffer(); m_nal_size_size = 1 + (buf[21] & 3); // Parameter sets in this order: vps, sps, pps, sei auto num_parameter_sets = static_cast<unsigned int>(buf[22]); auto pos = static_cast<size_t>(23); while (num_parameter_sets && (mpriv->get_size() > (pos + 3))) { auto nal_unit_count = get_uint16_be(&buf[pos + 1]); pos += 3; while (nal_unit_count && (mpriv->get_size() > pos)) { if (!write_nal(buf, pos, mpriv->get_size(), 2)) return; --nal_unit_count; --num_parameter_sets; } } }
uint16_t mm_io_c::read_uint16_be() { unsigned char buffer[2]; if (read(buffer, 2) != 2) throw mtx::mm_io::end_of_file_x(); return get_uint16_be(buffer); }
void real_reader_c::parse_headers() { if (rmff_read_headers(file) != RMFF_ERR_OK) return; int ndx; for (ndx = 0; ndx < file->num_tracks; ndx++) { rmff_track_t *track = file->tracks[ndx]; if ((RMFF_TRACK_TYPE_UNKNOWN == track->type) || (get_uint32_be(&track->mdpr_header.type_specific_size) == 0)) continue; if ((RMFF_TRACK_TYPE_VIDEO == track->type) && !demuxing_requested('v', track->id)) continue; if ((RMFF_TRACK_TYPE_AUDIO == track->type) && !demuxing_requested('a', track->id)) continue; if ((NULL == track->mdpr_header.mime_type) || ( strcmp(track->mdpr_header.mime_type, "audio/x-pn-realaudio") && strcmp(track->mdpr_header.mime_type, "video/x-pn-realvideo"))) continue; unsigned char *ts_data = track->mdpr_header.type_specific_data; uint32_t ts_size = get_uint32_be(&track->mdpr_header.type_specific_size); real_demuxer_cptr dmx(new real_demuxer_t(track)); if (RMFF_TRACK_TYPE_VIDEO == track->type) { dmx->rvp = (real_video_props_t *)track->mdpr_header.type_specific_data; memcpy(dmx->fourcc, &dmx->rvp->fourcc2, 4); dmx->fourcc[4] = 0; dmx->width = get_uint16_be(&dmx->rvp->width); dmx->height = get_uint16_be(&dmx->rvp->height); uint32_t i = get_uint32_be(&dmx->rvp->fps); dmx->fps = (float)((i & 0xffff0000) >> 16) + ((float)(i & 0x0000ffff)) / 65536.0; dmx->private_data = (unsigned char *)safememdup(ts_data, ts_size); dmx->private_size = ts_size; demuxers.push_back(dmx); } else if (RMFF_TRACK_TYPE_AUDIO == track->type) {
file_status_e pgssup_reader_c::read(generic_packetizer_c *, bool) { try { if (m_debug) mxinfo(boost::format("pgssup_reader_c::read(): ---------- start read at %1%\n") % m_in->getFilePointer()); if (PGSSUP_FILE_MAGIC != m_in->read_uint16_be()) return flush_packetizers(); uint64_t timestamp = static_cast<uint64_t>(m_in->read_uint32_be()) * 100000Lu / 9; m_in->skip(4); memory_cptr frame = memory_c::alloc(3); if (3 != m_in->read(frame->get_buffer(), 3)) return flush_packetizers(); unsigned int segment_size = get_uint16_be(frame->get_buffer() + 1); frame->resize(3 + segment_size); if (segment_size != m_in->read(frame->get_buffer() + 3, segment_size)) return flush_packetizers(); if (m_debug) mxinfo(boost::format("pgssup_reader_c::read(): type %|1$02x| size %2% at %3%\n") % static_cast<unsigned int>(frame->get_buffer()[0]) % segment_size % (m_in->getFilePointer() - 10 - 3)); PTZR0->process(new packet_t(frame, timestamp)); } catch (...) { if (m_debug) mxinfo("pgssup_reader_c::read(): exception\n"); return flush_packetizers(); } return FILE_STATUS_MOREDATA; }
dmx->fourcc[4] = 0; dmx->width = get_uint16_be(&dmx->rvp->width); dmx->height = get_uint16_be(&dmx->rvp->height); uint32_t i = get_uint32_be(&dmx->rvp->fps); dmx->fps = (float)((i & 0xffff0000) >> 16) + ((float)(i & 0x0000ffff)) / 65536.0; dmx->private_data = memory_c::clone(ts_data, ts_size); demuxers.push_back(dmx); } else if (RMFF_TRACK_TYPE_AUDIO == track->type) { bool ok = true; dmx->ra4p = (real_audio_v4_props_t *)track->mdpr_header.type_specific_data; dmx->ra5p = (real_audio_v5_props_t *)track->mdpr_header.type_specific_data; int version = get_uint16_be(&dmx->ra4p->version1); if (3 == version) { dmx->samples_per_second = 8000; dmx->channels = 1; dmx->bits_per_sample = 16; strcpy(dmx->fourcc, "14_4"); } else if (4 == version) { dmx->samples_per_second = get_uint16_be(&dmx->ra4p->sample_rate); dmx->channels = get_uint16_be(&dmx->ra4p->channels); dmx->bits_per_sample = get_uint16_be(&dmx->ra4p->sample_size); unsigned char *p = (unsigned char *)(dmx->ra4p + 1); int slen = p[0]; p += (slen + 1);
int16_t get_int16_be(uint8_t *buffer) { return((int16_t)get_uint16_be(buffer)); }
int64_t spu_extract_duration(unsigned char *data, size_t buf_size, int64_t timecode) { uint32_t date, control_start, next_off, start_off, off; unsigned char type; int duration; bool unknown; control_start = get_uint16_be(data + 2); next_off = control_start; duration = -1; start_off = 0; while ((start_off != next_off) && (next_off < buf_size)) { start_off = next_off; date = get_uint16_be(data + start_off) * 1024; next_off = get_uint16_be(data + start_off + 2); if (next_off < start_off) { mxwarn(boost::format(Y("spu_extraction_duration: Encountered broken SPU packet (next_off < start_off) at timecode %1%. " "This packet might be displayed incorrectly or not at all.\n")) % format_timecode(timecode, 3)); return -1; } mxverb(4, boost::format("spu_extraction_duration: date = %1%\n") % date); off = start_off + 4; for (type = data[off++]; type != 0xff; type = data[off++]) { mxverb(4, boost::format("spu_extraction_duration: cmd = %1% ") % type); unknown = false; switch(type) { case 0x00: /* Menu ID, 1 byte */ mxverb(4, "menu ID"); break; case 0x01: /* Start display */ mxverb(4, "start display"); break; case 0x02: /* Stop display */ mxverb(4, boost::format("stop display: %1%") % (date / 90)); return (int64_t)date * 1000000 / 90; break; case 0x03: /* Palette */ mxverb(4, "palette"); off+=2; break; case 0x04: /* Alpha */ mxverb(4, "alpha"); off+=2; break; case 0x05: mxverb(4, "coords"); off+=6; break; case 0x06: mxverb(4, "graphic lines"); off+=4; break; case 0xff: /* All done, bye-bye */ mxverb(4, "done"); return duration; default: mxverb(4, boost::format("unknown (0x%|1$02x|), skipping %2% bytes.") % type % (next_off - off)); unknown = true; } mxverb(4, "\n"); if (unknown) break; } } return duration; }