00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <time.h>
00032 #include "avformat.h"
00033 #include "internal.h"
00034 #include "libavcodec/dvdata.h"
00035 #include "libavutil/intreadwrite.h"
00036 #include "libavutil/mathematics.h"
00037 #include "dv.h"
00038
00039 struct DVDemuxContext {
00040 const DVprofile* sys;
00041 AVFormatContext* fctx;
00042 AVStream* vst;
00043 AVStream* ast[4];
00044 AVPacket audio_pkt[4];
00045 uint8_t audio_buf[4][8192];
00046 int ach;
00047 int frames;
00048 uint64_t abytes;
00049 };
00050
00051 static inline uint16_t dv_audio_12to16(uint16_t sample)
00052 {
00053 uint16_t shift, result;
00054
00055 sample = (sample < 0x800) ? sample : sample | 0xf000;
00056 shift = (sample & 0xf00) >> 8;
00057
00058 if (shift < 0x2 || shift > 0xd) {
00059 result = sample;
00060 } else if (shift < 0x8) {
00061 shift--;
00062 result = (sample - (256 * shift)) << shift;
00063 } else {
00064 shift = 0xe - shift;
00065 result = ((sample + ((256 * shift) + 1)) << shift) - 1;
00066 }
00067
00068 return result;
00069 }
00070
00071
00072
00073
00074
00075
00076 static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t)
00077 {
00078 int offs;
00079
00080 switch (t) {
00081 case dv_audio_source:
00082 offs = (80*6 + 80*16*3 + 3);
00083 break;
00084 case dv_audio_control:
00085 offs = (80*6 + 80*16*4 + 3);
00086 break;
00087 case dv_video_control:
00088 offs = (80*5 + 48 + 5);
00089 break;
00090 default:
00091 return NULL;
00092 }
00093
00094 return frame[offs] == t ? &frame[offs] : NULL;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4],
00106 const DVprofile *sys)
00107 {
00108 int size, chan, i, j, d, of, smpls, freq, quant, half_ch;
00109 uint16_t lc, rc;
00110 const uint8_t* as_pack;
00111 uint8_t *pcm, ipcm;
00112
00113 as_pack = dv_extract_pack(frame, dv_audio_source);
00114 if (!as_pack)
00115 return 0;
00116
00117 smpls = as_pack[1] & 0x3f;
00118 freq = (as_pack[4] >> 3) & 0x07;
00119 quant = as_pack[4] & 0x07;
00120
00121 if (quant > 1)
00122 return -1;
00123
00124 size = (sys->audio_min_samples[freq] + smpls) * 4;
00125 half_ch = sys->difseg_size / 2;
00126
00127
00128
00129 ipcm = (sys->height == 720 && !(frame[1] & 0x0C)) ? 2 : 0;
00130 pcm = ppcm[ipcm++];
00131
00132
00133 for (chan = 0; chan < sys->n_difchan; chan++) {
00134
00135 for (i = 0; i < sys->difseg_size; i++) {
00136 frame += 6 * 80;
00137 if (quant == 1 && i == half_ch) {
00138
00139 pcm = ppcm[ipcm++];
00140 if (!pcm)
00141 break;
00142 }
00143
00144
00145 for (j = 0; j < 9; j++) {
00146 for (d = 8; d < 80; d += 2) {
00147 if (quant == 0) {
00148 of = sys->audio_shuffle[i][j] + (d - 8) / 2 * sys->audio_stride;
00149 if (of*2 >= size)
00150 continue;
00151
00152 pcm[of*2] = frame[d+1];
00153 pcm[of*2+1] = frame[d];
00154 if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00)
00155 pcm[of*2+1] = 0;
00156 } else {
00157 lc = ((uint16_t)frame[d] << 4) |
00158 ((uint16_t)frame[d+2] >> 4);
00159 rc = ((uint16_t)frame[d+1] << 4) |
00160 ((uint16_t)frame[d+2] & 0x0f);
00161 lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));
00162 rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));
00163
00164 of = sys->audio_shuffle[i%half_ch][j] + (d - 8) / 3 * sys->audio_stride;
00165 if (of*2 >= size)
00166 continue;
00167
00168 pcm[of*2] = lc & 0xff;
00169 pcm[of*2+1] = lc >> 8;
00170 of = sys->audio_shuffle[i%half_ch+half_ch][j] +
00171 (d - 8) / 3 * sys->audio_stride;
00172 pcm[of*2] = rc & 0xff;
00173 pcm[of*2+1] = rc >> 8;
00174 ++d;
00175 }
00176 }
00177
00178 frame += 16 * 80;
00179 }
00180 }
00181
00182
00183 pcm = ppcm[ipcm++];
00184 if (!pcm)
00185 break;
00186 }
00187
00188 return size;
00189 }
00190
00191 static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
00192 {
00193 const uint8_t* as_pack;
00194 int freq, stype, smpls, quant, i, ach;
00195
00196 as_pack = dv_extract_pack(frame, dv_audio_source);
00197 if (!as_pack || !c->sys) {
00198 c->ach = 0;
00199 return 0;
00200 }
00201
00202 smpls = as_pack[1] & 0x3f;
00203 freq = (as_pack[4] >> 3) & 0x07;
00204 stype = (as_pack[3] & 0x1f);
00205 quant = as_pack[4] & 0x07;
00206
00207
00208 ach = ((int[4]){ 1, 0, 2, 4})[stype];
00209 if (ach == 1 && quant && freq == 2)
00210 ach = 2;
00211
00212
00213 for (i = 0; i < ach; i++) {
00214 if (!c->ast[i]) {
00215 c->ast[i] = avformat_new_stream(c->fctx, NULL);
00216 if (!c->ast[i])
00217 break;
00218 avpriv_set_pts_info(c->ast[i], 64, 1, 30000);
00219 c->ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00220 c->ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE;
00221
00222 av_init_packet(&c->audio_pkt[i]);
00223 c->audio_pkt[i].size = 0;
00224 c->audio_pkt[i].data = c->audio_buf[i];
00225 c->audio_pkt[i].stream_index = c->ast[i]->index;
00226 c->audio_pkt[i].flags |= AV_PKT_FLAG_KEY;
00227 }
00228 c->ast[i]->codec->sample_rate = dv_audio_frequency[freq];
00229 c->ast[i]->codec->channels = 2;
00230 c->ast[i]->codec->bit_rate = 2 * dv_audio_frequency[freq] * 16;
00231 c->ast[i]->start_time = 0;
00232 }
00233 c->ach = i;
00234
00235 return (c->sys->audio_min_samples[freq] + smpls) * 4; ;
00236 }
00237
00238 static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
00239 {
00240 const uint8_t* vsc_pack;
00241 AVCodecContext* avctx;
00242 int apt, is16_9;
00243 int size = 0;
00244
00245 if (c->sys) {
00246 avctx = c->vst->codec;
00247
00248 avpriv_set_pts_info(c->vst, 64, c->sys->time_base.num,
00249 c->sys->time_base.den);
00250 avctx->time_base= c->sys->time_base;
00251 if (!avctx->width){
00252 avctx->width = c->sys->width;
00253 avctx->height = c->sys->height;
00254 }
00255 avctx->pix_fmt = c->sys->pix_fmt;
00256
00257
00258 vsc_pack = dv_extract_pack(frame, dv_video_control);
00259 apt = frame[4] & 0x07;
00260 is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 ||
00261 (!apt && (vsc_pack[2] & 0x07) == 0x07)));
00262 c->vst->sample_aspect_ratio = c->sys->sar[is16_9];
00263 avctx->bit_rate = av_rescale_q(c->sys->frame_size, (AVRational){8,1},
00264 c->sys->time_base);
00265 size = c->sys->frame_size;
00266 }
00267 return size;
00268 }
00269
00270
00271
00272
00273
00274 DVDemuxContext* avpriv_dv_init_demux(AVFormatContext *s)
00275 {
00276 DVDemuxContext *c;
00277
00278 c = av_mallocz(sizeof(DVDemuxContext));
00279 if (!c)
00280 return NULL;
00281
00282 c->vst = avformat_new_stream(s, NULL);
00283 if (!c->vst) {
00284 av_free(c);
00285 return NULL;
00286 }
00287
00288 c->sys = NULL;
00289 c->fctx = s;
00290 memset(c->ast, 0, sizeof(c->ast));
00291 c->ach = 0;
00292 c->frames = 0;
00293 c->abytes = 0;
00294
00295 c->vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00296 c->vst->codec->codec_id = CODEC_ID_DVVIDEO;
00297 c->vst->codec->bit_rate = 25000000;
00298 c->vst->start_time = 0;
00299
00300 return c;
00301 }
00302
00303 int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
00304 {
00305 int size = -1;
00306 int i;
00307
00308 for (i = 0; i < c->ach; i++) {
00309 if (c->ast[i] && c->audio_pkt[i].size) {
00310 *pkt = c->audio_pkt[i];
00311 c->audio_pkt[i].size = 0;
00312 size = pkt->size;
00313 break;
00314 }
00315 }
00316
00317 return size;
00318 }
00319
00320 int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
00321 uint8_t* buf, int buf_size, int64_t pos)
00322 {
00323 int size, i;
00324 uint8_t *ppcm[4] = {0};
00325
00326 if (buf_size < DV_PROFILE_BYTES ||
00327 !(c->sys = avpriv_dv_frame_profile(c->sys, buf, buf_size)) ||
00328 buf_size < c->sys->frame_size) {
00329 return -1;
00330 }
00331
00332
00333
00334 size = dv_extract_audio_info(c, buf);
00335 for (i = 0; i < c->ach; i++) {
00336 c->audio_pkt[i].pos = pos;
00337 c->audio_pkt[i].size = size;
00338 c->audio_pkt[i].pts = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate;
00339 ppcm[i] = c->audio_buf[i];
00340 }
00341 dv_extract_audio(buf, ppcm, c->sys);
00342
00343
00344
00345 if (c->sys->height == 720) {
00346 if (buf[1] & 0x0C) {
00347 c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
00348 } else {
00349 c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
00350 c->abytes += size;
00351 }
00352 } else {
00353 c->abytes += size;
00354 }
00355
00356
00357 size = dv_extract_video_info(c, buf);
00358 av_init_packet(pkt);
00359 pkt->data = buf;
00360 pkt->pos = pos;
00361 pkt->size = size;
00362 pkt->flags |= AV_PKT_FLAG_KEY;
00363 pkt->stream_index = c->vst->id;
00364 pkt->pts = c->frames;
00365
00366 c->frames++;
00367
00368 return size;
00369 }
00370
00371 static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
00372 int64_t timestamp, int flags)
00373 {
00374
00375 const DVprofile* sys = avpriv_dv_codec_profile(c->vst->codec);
00376 int64_t offset;
00377 int64_t size = avio_size(s->pb) - s->data_offset;
00378 int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size;
00379
00380 offset = sys->frame_size * timestamp;
00381
00382 if (size >= 0 && offset > max_offset) offset = max_offset;
00383 else if (offset < 0) offset = 0;
00384
00385 return offset + s->data_offset;
00386 }
00387
00388 void dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
00389 {
00390 c->frames= frame_offset;
00391 if (c->ach)
00392 c->abytes= av_rescale_q(c->frames, c->sys->time_base,
00393 (AVRational){8, c->ast[0]->codec->bit_rate});
00394 c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
00395 c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
00396 }
00397
00398
00399
00400
00401
00402 typedef struct RawDVContext {
00403 DVDemuxContext* dv_demux;
00404 uint8_t buf[DV_MAX_FRAME_SIZE];
00405 } RawDVContext;
00406
00407 static int dv_read_header(AVFormatContext *s,
00408 AVFormatParameters *ap)
00409 {
00410 unsigned state, marker_pos = 0;
00411 RawDVContext *c = s->priv_data;
00412
00413 c->dv_demux = avpriv_dv_init_demux(s);
00414 if (!c->dv_demux)
00415 return -1;
00416
00417 state = avio_rb32(s->pb);
00418 while ((state & 0xffffff7f) != 0x1f07003f) {
00419 if (url_feof(s->pb)) {
00420 av_log(s, AV_LOG_ERROR, "Cannot find DV header.\n");
00421 return -1;
00422 }
00423 if (state == 0x003f0700 || state == 0xff3f0700)
00424 marker_pos = avio_tell(s->pb);
00425 if (state == 0xff3f0701 && avio_tell(s->pb) - marker_pos == 80) {
00426 avio_seek(s->pb, -163, SEEK_CUR);
00427 state = avio_rb32(s->pb);
00428 break;
00429 }
00430 state = (state << 8) | avio_r8(s->pb);
00431 }
00432 AV_WB32(c->buf, state);
00433
00434 if (avio_read(s->pb, c->buf + 4, DV_PROFILE_BYTES - 4) <= 0 ||
00435 avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0)
00436 return AVERROR(EIO);
00437
00438 c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES);
00439 if (!c->dv_demux->sys) {
00440 av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n");
00441 return -1;
00442 }
00443
00444 s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size, (AVRational){8,1},
00445 c->dv_demux->sys->time_base);
00446
00447 return 0;
00448 }
00449
00450
00451 static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
00452 {
00453 int size;
00454 RawDVContext *c = s->priv_data;
00455
00456 size = avpriv_dv_get_packet(c->dv_demux, pkt);
00457
00458 if (size < 0) {
00459 int64_t pos = avio_tell(s->pb);
00460 if (!c->dv_demux->sys)
00461 return AVERROR(EIO);
00462 size = c->dv_demux->sys->frame_size;
00463 if (avio_read(s->pb, c->buf, size) <= 0)
00464 return AVERROR(EIO);
00465
00466 size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size, pos);
00467 }
00468
00469 return size;
00470 }
00471
00472 static int dv_read_seek(AVFormatContext *s, int stream_index,
00473 int64_t timestamp, int flags)
00474 {
00475 RawDVContext *r = s->priv_data;
00476 DVDemuxContext *c = r->dv_demux;
00477 int64_t offset = dv_frame_offset(s, c, timestamp, flags);
00478
00479 if (avio_seek(s->pb, offset, SEEK_SET) < 0)
00480 return -1;
00481
00482 dv_offset_reset(c, offset / c->sys->frame_size);
00483 return 0;
00484 }
00485
00486 static int dv_read_close(AVFormatContext *s)
00487 {
00488 RawDVContext *c = s->priv_data;
00489 av_free(c->dv_demux);
00490 return 0;
00491 }
00492
00493 static int dv_probe(AVProbeData *p)
00494 {
00495 unsigned state, marker_pos = 0;
00496 int i;
00497 int matches = 0;
00498 int secondary_matches = 0;
00499
00500 if (p->buf_size < 5)
00501 return 0;
00502
00503 state = AV_RB32(p->buf);
00504 for (i = 4; i < p->buf_size; i++) {
00505 if ((state & 0xffffff7f) == 0x1f07003f)
00506 matches++;
00507
00508
00509 if ((state & 0xff07ff7f) == 0x1f07003f)
00510 secondary_matches++;
00511 if (state == 0x003f0700 || state == 0xff3f0700)
00512 marker_pos = i;
00513 if (state == 0xff3f0701 && i - marker_pos == 80)
00514 matches++;
00515 state = (state << 8) | p->buf[i];
00516 }
00517
00518 if (matches && p->buf_size / matches < 1024*1024) {
00519 if (matches > 4 || (secondary_matches >= 10 && p->buf_size / secondary_matches < 24000))
00520 return AVPROBE_SCORE_MAX*3/4;
00521 return AVPROBE_SCORE_MAX/4;
00522 }
00523 return 0;
00524 }
00525
00526 #if CONFIG_DV_DEMUXER
00527 AVInputFormat ff_dv_demuxer = {
00528 .name = "dv",
00529 .long_name = NULL_IF_CONFIG_SMALL("DV video format"),
00530 .priv_data_size = sizeof(RawDVContext),
00531 .read_probe = dv_probe,
00532 .read_header = dv_read_header,
00533 .read_packet = dv_read_packet,
00534 .read_close = dv_read_close,
00535 .read_seek = dv_read_seek,
00536 .extensions = "dv,dif",
00537 };
00538 #endif