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