From 8504157aca0f904bcdf840f2777da8bd6aa18e6f Mon Sep 17 00:00:00 2001
From: Aleksandr Slobodeniuk <alenuke@yandex.ru>
Date: Sun, 12 Nov 2017 02:52:47 +0300
Subject: [PATCH] avformat/dv: change dv audio format endianess to BE.

Reason: DV stores BE audio, so we remove unnecessary byteswap to LE.
---
 libavformat/dv.c      | 51 +++++++++++++++++++++++----------------------------
 libavformat/dvenc.c   | 14 +++++++-------
 libavformat/mov.c     |  2 +-
 libavformat/version.h |  2 +-
 4 files changed, 32 insertions(+), 37 deletions(-)

diff --git a/libavformat/dv.c b/libavformat/dv.c
index 06de044..9ebf81a 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -116,13 +116,13 @@ static const int dv_audio_frequency[3] = {
  * 3. Audio is always returned as 16-bit linear samples: 12-bit nonlinear samples
  *    are converted into 16-bit linear ones.
  */
-static int dv_extract_audio(const uint8_t *frame, uint8_t **ppcm,
+static int dv_extract_audio(const uint8_t *frame, uint16_t **ppcm,
                             const AVDVProfile *sys)
 {
     int size, chan, i, j, d, of, smpls, freq, quant, half_ch;
-    uint16_t lc, rc;
+    uint16_t lc, rc, *pcm;
     const uint8_t *as_pack;
-    uint8_t *pcm, ipcm;
+    uint8_t ipcm;
 
     as_pack = dv_extract_pack(frame, dv_audio_source);
     if (!as_pack)    /* No audio ? */
@@ -168,23 +168,25 @@ static int dv_extract_audio(const uint8_t *frame, uint8_t **ppcm,
                     break;
             }
 
-            /* for each AV sequence */
-            for (j = 0; j < 9; j++) {
-                for (d = 8; d < 80; d += 2) {
-                    if (quant == 0) {  /* 16-bit quantization */
+            if (quant == 0) { /* 16-bit quantization */
+                /* for each AV sequence */
+                for (j = 0; j < 9; j++) {
+                    for (d = 4; d < 40; d += 1) {
                         of = sys->audio_shuffle[i][j] +
-                             (d - 8) / 2 * sys->audio_stride;
+                             (d - 4) * sys->audio_stride;
                         if (of * 2 >= size)
                             continue;
 
-                        /* FIXME: maybe we have to admit that DV is a
-                         * big-endian PCM */
-                        pcm[of * 2]     = frame[d + 1];
-                        pcm[of * 2 + 1] = frame[d];
-
-                        if (pcm[of * 2 + 1] == 0x80 && pcm[of * 2] == 0x00)
-                            pcm[of * 2 + 1] = 0;
-                    } else {           /* 12-bit quantization */
+                        pcm[of] = ((uint16_t*)frame)[d];
+                        if (pcm[of] == av_be2ne16(0x8000))
+                            pcm[of] = 0;
+                    }
+                    frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
+                }
+            } else { /* 12-bit quantization */
+                /* for each AV sequence */
+                for (j = 0; j < 9; j++) {
+                    for (d = 8; d < 80; d += 2) {
                         lc = ((uint16_t)frame[d]     << 4) |
                              ((uint16_t)frame[d + 2] >> 4);
                         rc = ((uint16_t)frame[d + 1] << 4) |
@@ -197,21 +199,14 @@ static int dv_extract_audio(const uint8_t *frame, uint8_t **ppcm,
                         if (of * 2 >= size)
                             continue;
 
-                        /* FIXME: maybe we have to admit that DV is a
-                         * big-endian PCM */
-                        pcm[of * 2]     = lc & 0xff;
-                        pcm[of * 2 + 1] = lc >> 8;
+                        pcm[of] = av_be2ne16(lc);
                         of = sys->audio_shuffle[i % half_ch + half_ch][j] +
                              (d - 8) / 3 * sys->audio_stride;
-                        /* FIXME: maybe we have to admit that DV is a
-                         * big-endian PCM */
-                        pcm[of * 2]     = rc & 0xff;
-                        pcm[of * 2 + 1] = rc >> 8;
+                        pcm[of] = av_be2ne16(rc);
                         ++d;
                     }
+                    frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
                 }
-
-                frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
             }
         }
     }
@@ -260,7 +255,7 @@ static int dv_extract_audio_info(DVDemuxContext *c, const uint8_t *frame)
                 break;
             avpriv_set_pts_info(c->ast[i], 64, 1, 30000);
             c->ast[i]->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
-            c->ast[i]->codecpar->codec_id   = AV_CODEC_ID_PCM_S16LE;
+            c->ast[i]->codecpar->codec_id   = AV_CODEC_ID_PCM_S16BE;
 
             av_init_packet(&c->audio_pkt[i]);
             c->audio_pkt[i].size         = 0;
@@ -384,7 +379,7 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
         ppcm[i] = c->audio_buf[i];
     }
     if (c->ach)
-        dv_extract_audio(buf, ppcm, c->sys);
+        dv_extract_audio(buf, (uint16_t**)ppcm, c->sys);
 
     /* We work with 720p frames split in half, thus even frames have
      * channels 0,1 and odd 2,3. */
diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c
index 93c103b..99852a4 100644
--- a/libavformat/dvenc.c
+++ b/libavformat/dvenc.c
@@ -193,13 +193,13 @@ static void dv_inject_audio(DVMuxContext *c, int channel, uint8_t* frame_ptr)
         frame_ptr += 6 * 80; /* skip DIF segment header */
         for (j = 0; j < 9; j++) {
             dv_write_pack(dv_aaux_packs_dist[i][j], c, &frame_ptr[3], channel, i >= c->sys->difseg_size/2);
-            for (d = 8; d < 80; d+=2) {
-                of = c->sys->audio_shuffle[i][j] + (d - 8)/2 * c->sys->audio_stride;
+            for (d = 4; d < 40; d++) {
+                of = c->sys->audio_shuffle[i][j] + (d - 4) * c->sys->audio_stride;
                 if (of*2 >= size)
                     continue;
 
-                frame_ptr[d]   = *av_fifo_peek2(c->audio_data[channel], of*2+1); // FIXME: maybe we have to admit
-                frame_ptr[d+1] = *av_fifo_peek2(c->audio_data[channel], of*2);   //        that DV is a big-endian PCM
+                ((uint16_t*)frame_ptr)[d] =
+                    *(uint16_t*)av_fifo_peek2(c->audio_data[channel], of*2);
             }
             frame_ptr += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
         }
@@ -334,7 +334,7 @@ static DVMuxContext* dv_init_mux(AVFormatContext* s)
         goto bail_out;
     for (i=0; i<c->n_ast; i++) {
         if (c->ast[i]) {
-            if(c->ast[i]->codecpar->codec_id    != AV_CODEC_ID_PCM_S16LE ||
+            if(c->ast[i]->codecpar->codec_id    != AV_CODEC_ID_PCM_S16BE ||
                c->ast[i]->codecpar->channels    != 2)
                 goto bail_out;
             if (c->ast[i]->codecpar->sample_rate != 48000 &&
@@ -398,7 +398,7 @@ static int dv_write_header(AVFormatContext *s)
     if (!dv_init_mux(s)) {
         av_log(s, AV_LOG_ERROR, "Can't initialize DV format!\n"
                     "Make sure that you supply exactly two streams:\n"
-                    "     video: 25fps or 29.97fps, audio: 2ch/48|44|32kHz/PCM\n"
+                    "     video: 25fps or 29.97fps, audio: 2ch/48|44|32kHz/PCM S16 BE\n"
                     "     (50Mbps allows an optional second audio stream)\n");
         return -1;
     }
@@ -447,7 +447,7 @@ AVOutputFormat ff_dv_muxer = {
     .long_name         = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
     .extensions        = "dv",
     .priv_data_size    = sizeof(DVMuxContext),
-    .audio_codec       = AV_CODEC_ID_PCM_S16LE,
+    .audio_codec       = AV_CODEC_ID_PCM_S16BE,
     .video_codec       = AV_CODEC_ID_DVVIDEO,
     .write_header      = dv_write_header,
     .write_packet      = dv_write_packet,
diff --git a/libavformat/mov.c b/libavformat/mov.c
index fd170ba..ceaa952 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -2342,7 +2342,7 @@ static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
             return AVERROR(ENOMEM);
         }
         sc->dv_audio_container = 1;
-        st->codecpar->codec_id    = AV_CODEC_ID_PCM_S16LE;
+        st->codecpar->codec_id    = AV_CODEC_ID_PCM_S16BE;
         break;
 #endif
     /* no ifdef since parameters are always those */
diff --git a/libavformat/version.h b/libavformat/version.h
index 509a483..4b7ee26 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -33,7 +33,7 @@
 // Also please add any ticket numbers that you believe might be affected here
 #define LIBAVFORMAT_VERSION_MAJOR  58
 #define LIBAVFORMAT_VERSION_MINOR   2
-#define LIBAVFORMAT_VERSION_MICRO 100
+#define LIBAVFORMAT_VERSION_MICRO 101
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \
-- 
2.7.1.windows.1

