]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/dv.c
Windows Media Audio Lossless decoder
[ffmpeg] / libavcodec / dv.c
index e5cade503326263fbeeaace5f61d9607e4ac4831..3deaa5e2eebd712af439cf0a46ae3ff7557122c5 100644 (file)
  * @file
  * DV codec.
  */
-#define ALT_BITSTREAM_READER
+
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "put_bits.h"
 #include "simple_idct.h"
 #include "dvdata.h"
+#include "dvquant.h"
 #include "dv_tablegen.h"
 
 //#undef NDEBUG
@@ -312,13 +314,13 @@ static av_cold int dvvideo_init(AVCodecContext *avctx)
             dv_rl_vlc[i].level = level;
             dv_rl_vlc[i].run   = run;
         }
-        free_vlc(&dv_vlc);
+        ff_free_vlc(&dv_vlc);
 
         dv_vlc_map_tableinit();
     }
 
     /* Generic DSP setup */
-    dsputil_init(&dsp, avctx);
+    ff_dsputil_init(&dsp, avctx);
     ff_set_cmp(&dsp, dsp.ildct_cmp, avctx->ildct_cmp);
     s->get_pixels = dsp.get_pixels;
     s->ildct_cmp = dsp.ildct_cmp[5];
@@ -349,7 +351,7 @@ static av_cold int dvvideo_init(AVCodecContext *avctx)
 
 static av_cold int dvvideo_init_encoder(AVCodecContext *avctx)
 {
-    if (!ff_dv_codec_profile(avctx)) {
+    if (!avpriv_dv_codec_profile(avctx)) {
         av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video\n",
                avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt));
         return -1;
@@ -364,7 +366,7 @@ typedef struct BlockInfo {
     uint8_t pos; /* position in block */
     void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block);
     uint8_t partial_bit_count;
-    uint16_t partial_bit_buffer;
+    uint32_t partial_bit_buffer;
     int shift_offset;
 } BlockInfo;
 
@@ -392,8 +394,7 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block)
 
     /* if we must parse a partial VLC, we do it here */
     if (partial_bit_count > 0) {
-        re_cache = ((unsigned)re_cache >> partial_bit_count) |
-                   (mb->partial_bit_buffer << (sizeof(re_cache) * 8 - partial_bit_count));
+        re_cache = re_cache >> partial_bit_count | mb->partial_bit_buffer;
         re_index -= partial_bit_count;
         mb->partial_bit_count = 0;
     }
@@ -416,7 +417,7 @@ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block)
         if (re_index + vlc_len > last_index) {
             /* should be < 16 bits otherwise a codeword could have been parsed */
             mb->partial_bit_count = last_index - re_index;
-            mb->partial_bit_buffer = NEG_USR32(re_cache, mb->partial_bit_count);
+            mb->partial_bit_buffer = re_cache & ~(-1u >> mb->partial_bit_count);
             re_index = last_index;
             break;
         }
@@ -543,7 +544,7 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
         block = block1;
         mb    = mb1;
         init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb));
-        put_bits32(&pb, 0); // padding must be zero'ed
+        put_bits32(&pb, 0); // padding must be zeroed
         flush_put_bits(&pb);
         for (j = 0; j < s->sys->bpm; j++, block += 64, mb++) {
             if (mb->pos < 64 && get_bits_left(&gb) > 0) {
@@ -564,7 +565,7 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
     block = &sblock[0][0];
     mb    = mb_data;
     init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb));
-    put_bits32(&vs_pb, 0); // padding must be zero'ed
+    put_bits32(&vs_pb, 0); // padding must be zeroed
     flush_put_bits(&vs_pb);
     for (mb_index = 0; mb_index < 5; mb_index++) {
         for (j = 0; j < s->sys->bpm; j++) {
@@ -758,7 +759,7 @@ static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data,
         if (ps > 0) {
             int is = s->ildct_cmp(NULL, data           , NULL, linesize<<1, 4) +
                      s->ildct_cmp(NULL, data + linesize, NULL, linesize<<1, 4);
-            return (ps > is);
+            return ps > is;
         }
     }
 
@@ -1072,7 +1073,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
     const uint8_t* vsc_pack;
     int apt, is16_9;
 
-    s->sys = ff_dv_frame_profile(s->sys, buf, buf_size);
+    s->sys = avpriv_dv_frame_profile(s->sys, buf, buf_size);
     if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys)) {
         av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n");
         return -1; /* NOTE: we only accept several full frames */
@@ -1190,6 +1191,41 @@ static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
 }
 
 #if CONFIG_DVVIDEO_ENCODER
+static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num,
+                                  uint8_t seq_num, uint8_t dif_num,
+                                  uint8_t* buf)
+{
+    buf[0] = (uint8_t)t;       /* Section type */
+    buf[1] = (seq_num  << 4) | /* DIF seq number 0-9 for 525/60; 0-11 for 625/50 */
+             (chan_num << 3) | /* FSC: for 50Mb/s 0 - first channel; 1 - second */
+             7;                /* reserved -- always 1 */
+    buf[2] = dif_num;          /* DIF block number Video: 0-134, Audio: 0-8 */
+    return 3;
+}
+
+
+static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf)
+{
+    if (syb_num == 0 || syb_num == 6) {
+        buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
+                 (0  << 4) | /* AP3 (Subcode application ID) */
+                 0x0f;       /* reserved -- always 1 */
+    }
+    else if (syb_num == 11) {
+        buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
+                 0x7f;       /* reserved -- always 1 */
+    }
+    else {
+        buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
+                 (0  << 4) | /* APT (Track application ID) */
+                 0x0f;       /* reserved -- always 1 */
+    }
+    buf[1] = 0xf0 |            /* reserved -- always 1 */
+             (syb_num & 0x0f); /* SSYB number 0 - 11   */
+    buf[2] = 0xff;             /* reserved -- always 1 */
+    return 3;
+}
+
 static void dv_format_frame(DVVideoContext* c, uint8_t* buf)
 {
     int chan, i, j, k;
@@ -1240,29 +1276,37 @@ static void dv_format_frame(DVVideoContext* c, uint8_t* buf)
 }
 
 
-static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size,
-                                void *data)
+static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt,
+                                const AVFrame *frame, int *got_packet)
 {
     DVVideoContext *s = c->priv_data;
+    int ret;
 
-    s->sys = ff_dv_codec_profile(c);
-    if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys))
+    s->sys = avpriv_dv_codec_profile(c);
+    if (!s->sys || dv_init_dynamic_tables(s->sys))
         return -1;
+    if ((ret = ff_alloc_packet(pkt, s->sys->frame_size)) < 0) {
+        av_log(c, AV_LOG_ERROR, "Error getting output packet.\n");
+        return ret;
+    }
 
     c->pix_fmt           = s->sys->pix_fmt;
-    s->picture           = *((AVFrame *)data);
+    s->picture           = *frame;
     s->picture.key_frame = 1;
     s->picture.pict_type = AV_PICTURE_TYPE_I;
 
-    s->buf = buf;
+    s->buf = pkt->data;
     c->execute(c, dv_encode_video_segment, s->sys->work_chunks, NULL,
                dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
 
     emms_c();
 
-    dv_format_frame(s, buf);
+    dv_format_frame(s, pkt->data);
 
-    return s->sys->frame_size;
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    *got_packet = 1;
+
+    return 0;
 }
 #endif
 
@@ -1279,12 +1323,12 @@ static int dvvideo_close(AVCodecContext *c)
 
 #if CONFIG_DVVIDEO_ENCODER
 AVCodec ff_dvvideo_encoder = {
-    "dvvideo",
-    AVMEDIA_TYPE_VIDEO,
-    CODEC_ID_DVVIDEO,
-    sizeof(DVVideoContext),
-    dvvideo_init_encoder,
-    dvvideo_encode_frame,
+    .name           = "dvvideo",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = CODEC_ID_DVVIDEO,
+    .priv_data_size = sizeof(DVVideoContext),
+    .init           = dvvideo_init_encoder,
+    .encode2        = dvvideo_encode_frame,
     .capabilities = CODEC_CAP_SLICE_THREADS,
     .pix_fmts  = (const enum PixelFormat[]) {PIX_FMT_YUV411P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, PIX_FMT_NONE},
     .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
@@ -1293,16 +1337,14 @@ AVCodec ff_dvvideo_encoder = {
 
 #if CONFIG_DVVIDEO_DECODER
 AVCodec ff_dvvideo_decoder = {
-    "dvvideo",
-    AVMEDIA_TYPE_VIDEO,
-    CODEC_ID_DVVIDEO,
-    sizeof(DVVideoContext),
-    dvvideo_init,
-    NULL,
-    dvvideo_close,
-    dvvideo_decode_frame,
-    CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
-    NULL,
+    .name           = "dvvideo",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = CODEC_ID_DVVIDEO,
+    .priv_data_size = sizeof(DVVideoContext),
+    .init           = dvvideo_init,
+    .close          = dvvideo_close,
+    .decode         = dvvideo_decode_frame,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
     .max_lowres = 3,
     .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
 };