00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028 #include <stdint.h>
00029
00030 #include "libavutil/intreadwrite.h"
00031
00032 #include "avformat.h"
00033 #include "internal.h"
00034 #include "riff.h"
00035 #include "libavutil/avassert.h"
00036
00038 #define XMV_MIN_HEADER_SIZE 36
00039
00041 #define XMV_AUDIO_ADPCM51_FRONTLEFTRIGHT 1
00042
00043 #define XMV_AUDIO_ADPCM51_FRONTCENTERLOW 2
00044
00045 #define XMV_AUDIO_ADPCM51_REARLEFTRIGHT 4
00046
00048 #define XMV_AUDIO_ADPCM51 (XMV_AUDIO_ADPCM51_FRONTLEFTRIGHT | \
00049 XMV_AUDIO_ADPCM51_FRONTCENTERLOW | \
00050 XMV_AUDIO_ADPCM51_REARLEFTRIGHT)
00051
00053 typedef struct XMVVideoPacket {
00054 int stream_index;
00055
00056 uint32_t data_size;
00057 uint64_t data_offset;
00058
00059 uint32_t current_frame;
00060 uint32_t frame_count;
00061
00062 int has_extradata;
00063 uint8_t extradata[4];
00064
00065 int64_t last_pts;
00066 int64_t pts;
00067 } XMVVideoPacket;
00068
00070 typedef struct XMVAudioPacket {
00071 int stream_index;
00072
00073
00074 uint16_t compression;
00075 uint16_t channels;
00076 uint32_t sample_rate;
00077 uint16_t bits_per_sample;
00078 uint32_t bit_rate;
00079 uint16_t flags;
00080 uint16_t block_align;
00081 uint16_t block_samples;
00082
00083 enum AVCodecID codec_id;
00084
00085 uint32_t data_size;
00086 uint64_t data_offset;
00087
00088 uint32_t frame_size;
00089
00090 uint64_t block_count;
00091 } XMVAudioPacket;
00092
00094 typedef struct XMVDemuxContext {
00095 uint16_t audio_track_count;
00096
00097 uint32_t this_packet_size;
00098 uint32_t next_packet_size;
00099
00100 uint64_t this_packet_offset;
00101 uint64_t next_packet_offset;
00102
00103 uint16_t current_stream;
00104 uint16_t stream_count;
00105
00106 XMVVideoPacket video;
00107 XMVAudioPacket *audio;
00108 } XMVDemuxContext;
00109
00110 static int xmv_probe(AVProbeData *p)
00111 {
00112 uint32_t file_version;
00113
00114 if (p->buf_size < XMV_MIN_HEADER_SIZE)
00115 return 0;
00116
00117 file_version = AV_RL32(p->buf + 16);
00118 if ((file_version == 0) || (file_version > 4))
00119 return 0;
00120
00121 if (!memcmp(p->buf + 12, "xobX", 4))
00122 return AVPROBE_SCORE_MAX;
00123
00124 return 0;
00125 }
00126
00127 static int xmv_read_header(AVFormatContext *s)
00128 {
00129 XMVDemuxContext *xmv = s->priv_data;
00130 AVIOContext *pb = s->pb;
00131 AVStream *vst = NULL;
00132
00133 uint32_t file_version;
00134 uint32_t this_packet_size;
00135 uint16_t audio_track;
00136
00137 avio_skip(pb, 4);
00138
00139 this_packet_size = avio_rl32(pb);
00140
00141 avio_skip(pb, 4);
00142 avio_skip(pb, 4);
00143
00144 file_version = avio_rl32(pb);
00145 if ((file_version != 4) && (file_version != 2))
00146 av_log_ask_for_sample(s, "Found uncommon version %d\n", file_version);
00147
00148
00149
00150
00151 vst = avformat_new_stream(s, NULL);
00152 if (!vst)
00153 return AVERROR(ENOMEM);
00154
00155 avpriv_set_pts_info(vst, 32, 1, 1000);
00156
00157 vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00158 vst->codec->codec_id = AV_CODEC_ID_WMV2;
00159 vst->codec->codec_tag = MKBETAG('W', 'M', 'V', '2');
00160 vst->codec->width = avio_rl32(pb);
00161 vst->codec->height = avio_rl32(pb);
00162
00163 vst->duration = avio_rl32(pb);
00164
00165 xmv->video.stream_index = vst->index;
00166
00167
00168
00169 xmv->audio_track_count = avio_rl16(pb);
00170
00171 avio_skip(pb, 2);
00172
00173 xmv->audio = av_malloc(xmv->audio_track_count * sizeof(XMVAudioPacket));
00174 if (!xmv->audio)
00175 return AVERROR(ENOMEM);
00176
00177 for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {
00178 XMVAudioPacket *packet = &xmv->audio[audio_track];
00179 AVStream *ast = NULL;
00180
00181 packet->compression = avio_rl16(pb);
00182 packet->channels = avio_rl16(pb);
00183 packet->sample_rate = avio_rl32(pb);
00184 packet->bits_per_sample = avio_rl16(pb);
00185 packet->flags = avio_rl16(pb);
00186
00187 if (!packet->channels) {
00188 av_log(s, AV_LOG_ERROR, "0 channels\n");
00189 return AVERROR(EINVAL);
00190 }
00191
00192 packet->bit_rate = packet->bits_per_sample *
00193 packet->sample_rate *
00194 packet->channels;
00195 packet->block_align = 36 * packet->channels;
00196 packet->block_samples = 64;
00197 packet->codec_id = ff_wav_codec_get_id(packet->compression,
00198 packet->bits_per_sample);
00199
00200 packet->stream_index = -1;
00201
00202 packet->frame_size = 0;
00203 packet->block_count = 0;
00204
00205
00206
00207 if (packet->flags & XMV_AUDIO_ADPCM51)
00208 av_log(s, AV_LOG_WARNING, "Unsupported 5.1 ADPCM audio stream "
00209 "(0x%04X)\n", packet->flags);
00210
00211 ast = avformat_new_stream(s, NULL);
00212 if (!ast)
00213 return AVERROR(ENOMEM);
00214
00215 ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00216 ast->codec->codec_id = packet->codec_id;
00217 ast->codec->codec_tag = packet->compression;
00218 ast->codec->channels = packet->channels;
00219 ast->codec->sample_rate = packet->sample_rate;
00220 ast->codec->bits_per_coded_sample = packet->bits_per_sample;
00221 ast->codec->bit_rate = packet->bit_rate;
00222 ast->codec->block_align = 36 * packet->channels;
00223
00224 avpriv_set_pts_info(ast, 32, packet->block_samples, packet->sample_rate);
00225
00226 packet->stream_index = ast->index;
00227
00228 ast->duration = vst->duration;
00229 }
00230
00231
00232
00233
00234 xmv->next_packet_offset = avio_tell(pb);
00235 xmv->next_packet_size = this_packet_size - xmv->next_packet_offset;
00236 xmv->stream_count = xmv->audio_track_count + 1;
00237
00238 return 0;
00239 }
00240
00241 static void xmv_read_extradata(uint8_t *extradata, AVIOContext *pb)
00242 {
00243
00244
00245 uint32_t data = avio_rl32(pb);
00246
00247 int mspel_bit = !!(data & 0x01);
00248 int loop_filter = !!(data & 0x02);
00249 int abt_flag = !!(data & 0x04);
00250 int j_type_bit = !!(data & 0x08);
00251 int top_left_mv_flag = !!(data & 0x10);
00252 int per_mb_rl_bit = !!(data & 0x20);
00253 int slice_count = (data >> 6) & 7;
00254
00255
00256
00257 data = 0;
00258
00259 data |= mspel_bit << 15;
00260 data |= loop_filter << 14;
00261 data |= abt_flag << 13;
00262 data |= j_type_bit << 12;
00263 data |= top_left_mv_flag << 11;
00264 data |= per_mb_rl_bit << 10;
00265 data |= slice_count << 7;
00266
00267 AV_WB32(extradata, data);
00268 }
00269
00270 static int xmv_process_packet_header(AVFormatContext *s)
00271 {
00272 XMVDemuxContext *xmv = s->priv_data;
00273 AVIOContext *pb = s->pb;
00274
00275 uint8_t data[8];
00276 uint16_t audio_track;
00277 uint64_t data_offset;
00278
00279
00280 xmv->next_packet_size = avio_rl32(pb);
00281
00282
00283
00284 if (avio_read(pb, data, 8) != 8)
00285 return AVERROR(EIO);
00286
00287 xmv->video.data_size = AV_RL32(data) & 0x007FFFFF;
00288
00289 xmv->video.current_frame = 0;
00290 xmv->video.frame_count = (AV_RL32(data) >> 23) & 0xFF;
00291
00292 xmv->video.has_extradata = (data[3] & 0x80) != 0;
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 xmv->video.data_size -= xmv->audio_track_count * 4;
00304
00305 xmv->current_stream = 0;
00306 if (!xmv->video.frame_count) {
00307 xmv->video.frame_count = 1;
00308 xmv->current_stream = xmv->stream_count > 1;
00309 }
00310
00311
00312
00313 for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {
00314 XMVAudioPacket *packet = &xmv->audio[audio_track];
00315
00316 if (avio_read(pb, data, 4) != 4)
00317 return AVERROR(EIO);
00318
00319 packet->data_size = AV_RL32(data) & 0x007FFFFF;
00320 if ((packet->data_size == 0) && (audio_track != 0))
00321
00322
00323
00324
00325
00326 packet->data_size = xmv->audio[audio_track - 1].data_size;
00327
00328
00329 packet->frame_size = packet->data_size / xmv->video.frame_count;
00330 packet->frame_size -= packet->frame_size % packet->block_align;
00331 }
00332
00333
00334
00335 data_offset = avio_tell(pb);
00336
00337 xmv->video.data_offset = data_offset;
00338 data_offset += xmv->video.data_size;
00339
00340 for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {
00341 xmv->audio[audio_track].data_offset = data_offset;
00342 data_offset += xmv->audio[audio_track].data_size;
00343 }
00344
00345
00346
00347
00348 if (xmv->video.data_size > 0) {
00349 if (xmv->video.has_extradata) {
00350 xmv_read_extradata(xmv->video.extradata, pb);
00351
00352 xmv->video.data_size -= 4;
00353 xmv->video.data_offset += 4;
00354
00355 if (xmv->video.stream_index >= 0) {
00356 AVStream *vst = s->streams[xmv->video.stream_index];
00357
00358 av_assert0(xmv->video.stream_index < s->nb_streams);
00359
00360 if (vst->codec->extradata_size < 4) {
00361 av_free(vst->codec->extradata);
00362
00363 vst->codec->extradata =
00364 av_malloc(4 + FF_INPUT_BUFFER_PADDING_SIZE);
00365 vst->codec->extradata_size = 4;
00366 }
00367
00368 memcpy(vst->codec->extradata, xmv->video.extradata, 4);
00369 }
00370 }
00371 }
00372
00373 return 0;
00374 }
00375
00376 static int xmv_fetch_new_packet(AVFormatContext *s)
00377 {
00378 XMVDemuxContext *xmv = s->priv_data;
00379 AVIOContext *pb = s->pb;
00380 int result;
00381
00382
00383 xmv->this_packet_offset = xmv->next_packet_offset;
00384 if (avio_seek(pb, xmv->this_packet_offset, SEEK_SET) != xmv->this_packet_offset)
00385 return AVERROR(EIO);
00386
00387
00388 xmv->this_packet_size = xmv->next_packet_size;
00389 if (xmv->this_packet_size < (12 + xmv->audio_track_count * 4))
00390 return AVERROR(EIO);
00391
00392
00393 result = xmv_process_packet_header(s);
00394 if (result)
00395 return result;
00396
00397
00398 xmv->next_packet_offset = xmv->this_packet_offset + xmv->this_packet_size;
00399
00400 return 0;
00401 }
00402
00403 static int xmv_fetch_audio_packet(AVFormatContext *s,
00404 AVPacket *pkt, uint32_t stream)
00405 {
00406 XMVDemuxContext *xmv = s->priv_data;
00407 AVIOContext *pb = s->pb;
00408 XMVAudioPacket *audio = &xmv->audio[stream];
00409
00410 uint32_t data_size;
00411 uint32_t block_count;
00412 int result;
00413
00414
00415 if (avio_seek(pb, audio->data_offset, SEEK_SET) != audio->data_offset)
00416 return AVERROR(EIO);
00417
00418 if ((xmv->video.current_frame + 1) < xmv->video.frame_count)
00419
00420 data_size = FFMIN(audio->frame_size, audio->data_size);
00421 else
00422
00423 data_size = audio->data_size;
00424
00425
00426 result = av_get_packet(pb, pkt, data_size);
00427 if (result <= 0)
00428 return result;
00429
00430 pkt->stream_index = audio->stream_index;
00431
00432
00433
00434 block_count = data_size / audio->block_align;
00435
00436 pkt->duration = block_count;
00437 pkt->pts = audio->block_count;
00438 pkt->dts = AV_NOPTS_VALUE;
00439
00440 audio->block_count += block_count;
00441
00442
00443 audio->data_size -= data_size;
00444 audio->data_offset += data_size;
00445
00446 return 0;
00447 }
00448
00449 static int xmv_fetch_video_packet(AVFormatContext *s,
00450 AVPacket *pkt)
00451 {
00452 XMVDemuxContext *xmv = s->priv_data;
00453 AVIOContext *pb = s->pb;
00454 XMVVideoPacket *video = &xmv->video;
00455
00456 int result;
00457 uint32_t frame_header;
00458 uint32_t frame_size, frame_timestamp;
00459 uint8_t *data, *end;
00460
00461
00462 if (avio_seek(pb, video->data_offset, SEEK_SET) != video->data_offset)
00463 return AVERROR(EIO);
00464
00465
00466 frame_header = avio_rl32(pb);
00467
00468 frame_size = (frame_header & 0x1FFFF) * 4 + 4;
00469 frame_timestamp = (frame_header >> 17);
00470
00471 if ((frame_size + 4) > video->data_size)
00472 return AVERROR(EIO);
00473
00474
00475 result = av_get_packet(pb, pkt, frame_size);
00476 if (result != frame_size)
00477 return result;
00478
00479
00480
00481
00482
00483 for (data = pkt->data, end = pkt->data + frame_size; data < end; data += 4)
00484 AV_WB32(data, AV_RL32(data));
00485
00486 pkt->stream_index = video->stream_index;
00487
00488
00489
00490 video->last_pts = frame_timestamp + video->pts;
00491
00492 pkt->duration = 0;
00493 pkt->pts = video->last_pts;
00494 pkt->dts = AV_NOPTS_VALUE;
00495
00496 video->pts += frame_timestamp;
00497
00498
00499 pkt->flags = (pkt->data[0] & 0x80) ? 0 : AV_PKT_FLAG_KEY;
00500
00501
00502 video->data_size -= frame_size + 4;
00503 video->data_offset += frame_size + 4;
00504
00505 return 0;
00506 }
00507
00508 static int xmv_read_packet(AVFormatContext *s,
00509 AVPacket *pkt)
00510 {
00511 XMVDemuxContext *xmv = s->priv_data;
00512 int result;
00513
00514 if (xmv->video.current_frame == xmv->video.frame_count) {
00515
00516
00517 result = xmv_fetch_new_packet(s);
00518 if (result)
00519 return result;
00520 }
00521
00522 if (xmv->current_stream == 0) {
00523
00524
00525 result = xmv_fetch_video_packet(s, pkt);
00526 if (result)
00527 return result;
00528
00529 } else {
00530
00531
00532 result = xmv_fetch_audio_packet(s, pkt, xmv->current_stream - 1);
00533 if (result)
00534 return result;
00535 }
00536
00537
00538 if (++xmv->current_stream >= xmv->stream_count) {
00539 xmv->current_stream = 0;
00540 xmv->video.current_frame += 1;
00541 }
00542
00543 return 0;
00544 }
00545
00546 static int xmv_read_close(AVFormatContext *s)
00547 {
00548 XMVDemuxContext *xmv = s->priv_data;
00549
00550 av_freep(&xmv->audio);
00551
00552 return 0;
00553 }
00554
00555 AVInputFormat ff_xmv_demuxer = {
00556 .name = "xmv",
00557 .long_name = NULL_IF_CONFIG_SMALL("Microsoft XMV"),
00558 .priv_data_size = sizeof(XMVDemuxContext),
00559 .read_probe = xmv_probe,
00560 .read_header = xmv_read_header,
00561 .read_packet = xmv_read_packet,
00562 .read_close = xmv_read_close,
00563 };