Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/intreadwrite.h"
00023 #include "libavutil/intfloat.h"
00024 #include "avformat.h"
00025 #include "internal.h"
00026
00027 typedef struct ThpDemuxContext {
00028 int version;
00029 int first_frame;
00030 int first_framesz;
00031 int last_frame;
00032 int compoff;
00033 int framecnt;
00034 AVRational fps;
00035 int frame;
00036 int next_frame;
00037 int next_framesz;
00038 int video_stream_index;
00039 int audio_stream_index;
00040 int compcount;
00041 unsigned char components[16];
00042 AVStream* vst;
00043 int has_audio;
00044 int audiosize;
00045 } ThpDemuxContext;
00046
00047
00048 static int thp_probe(AVProbeData *p)
00049 {
00050
00051 if (AV_RL32(p->buf) == MKTAG('T', 'H', 'P', '\0'))
00052 return AVPROBE_SCORE_MAX;
00053 else
00054 return 0;
00055 }
00056
00057 static int thp_read_header(AVFormatContext *s,
00058 AVFormatParameters *ap)
00059 {
00060 ThpDemuxContext *thp = s->priv_data;
00061 AVStream *st;
00062 AVIOContext *pb = s->pb;
00063 int i;
00064
00065
00066 avio_rb32(pb);
00067 thp->version = avio_rb32(pb);
00068
00069 avio_rb32(pb);
00070 avio_rb32(pb);
00071
00072 thp->fps = av_d2q(av_int2float(avio_rb32(pb)), INT_MAX);
00073 thp->framecnt = avio_rb32(pb);
00074 thp->first_framesz = avio_rb32(pb);
00075 avio_rb32(pb);
00076
00077 thp->compoff = avio_rb32(pb);
00078 avio_rb32(pb);
00079 thp->first_frame = avio_rb32(pb);
00080 thp->last_frame = avio_rb32(pb);
00081
00082 thp->next_framesz = thp->first_framesz;
00083 thp->next_frame = thp->first_frame;
00084
00085
00086 avio_seek (pb, thp->compoff, SEEK_SET);
00087 thp->compcount = avio_rb32(pb);
00088
00089
00090 avio_read(pb, thp->components, 16);
00091
00092 for (i = 0; i < thp->compcount; i++) {
00093 if (thp->components[i] == 0) {
00094 if (thp->vst != 0)
00095 break;
00096
00097
00098 st = avformat_new_stream(s, NULL);
00099 if (!st)
00100 return AVERROR(ENOMEM);
00101
00102
00103
00104 avpriv_set_pts_info(st, 64, thp->fps.den, thp->fps.num);
00105 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00106 st->codec->codec_id = CODEC_ID_THP;
00107 st->codec->codec_tag = 0;
00108 st->codec->width = avio_rb32(pb);
00109 st->codec->height = avio_rb32(pb);
00110 st->codec->sample_rate = av_q2d(thp->fps);
00111 thp->vst = st;
00112 thp->video_stream_index = st->index;
00113
00114 if (thp->version == 0x11000)
00115 avio_rb32(pb);
00116 } else if (thp->components[i] == 1) {
00117 if (thp->has_audio != 0)
00118 break;
00119
00120
00121 st = avformat_new_stream(s, NULL);
00122 if (!st)
00123 return AVERROR(ENOMEM);
00124
00125 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00126 st->codec->codec_id = CODEC_ID_ADPCM_THP;
00127 st->codec->codec_tag = 0;
00128 st->codec->channels = avio_rb32(pb);
00129 st->codec->sample_rate = avio_rb32(pb);
00130
00131 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
00132
00133 thp->audio_stream_index = st->index;
00134 thp->has_audio = 1;
00135 }
00136 }
00137
00138 return 0;
00139 }
00140
00141 static int thp_read_packet(AVFormatContext *s,
00142 AVPacket *pkt)
00143 {
00144 ThpDemuxContext *thp = s->priv_data;
00145 AVIOContext *pb = s->pb;
00146 int size;
00147 int ret;
00148
00149 if (thp->audiosize == 0) {
00150
00151 if (thp->frame >= thp->framecnt)
00152 return AVERROR(EIO);
00153
00154 avio_seek(pb, thp->next_frame, SEEK_SET);
00155
00156
00157 thp->next_frame += thp->next_framesz;
00158 thp->next_framesz = avio_rb32(pb);
00159
00160 avio_rb32(pb);
00161 size = avio_rb32(pb);
00162
00163
00164
00165 if (thp->has_audio)
00166 thp->audiosize = avio_rb32(pb);
00167 else
00168 thp->frame++;
00169
00170 ret = av_get_packet(pb, pkt, size);
00171 if (ret != size) {
00172 av_free_packet(pkt);
00173 return AVERROR(EIO);
00174 }
00175
00176 pkt->stream_index = thp->video_stream_index;
00177 } else {
00178 ret = av_get_packet(pb, pkt, thp->audiosize);
00179 if (ret != thp->audiosize) {
00180 av_free_packet(pkt);
00181 return AVERROR(EIO);
00182 }
00183
00184 pkt->stream_index = thp->audio_stream_index;
00185 thp->audiosize = 0;
00186 thp->frame++;
00187 }
00188
00189 return 0;
00190 }
00191
00192 AVInputFormat ff_thp_demuxer = {
00193 .name = "thp",
00194 .long_name = NULL_IF_CONFIG_SMALL("THP"),
00195 .priv_data_size = sizeof(ThpDemuxContext),
00196 .read_probe = thp_probe,
00197 .read_header = thp_read_header,
00198 .read_packet = thp_read_packet
00199 };