[FFmpeg-devel] [RFC] LPCM 24 bits support

Giuliano Pochini pochini
Mon Mar 24 00:11:31 CET 2008


Hi all.

I have a music DVD with a DVD-V content without video and a stereo
96KHz/24 soundtrack. ffmpeg doesn't support it. Below is my first attempt
to add support for that format. It "almost" works, but I need help.

First, I don't know how to add a new codec properly. I just replaced
CODEC_ID_PCM_S16BE with CODEC_ID_LPCM_S24 in libavformat/mpeg.c in order to
make ffmpeg use my code.

The data is shuffled in blocks 12 bytes long. How can I tell the upper
layers of ffmpeg to not send anything that is not a multiple of 12 bytes ?

The (commented out) debug lines show that the function receives data in
batches 2004 bytes long. However the last 12 bytes are always 00, 00, 00,
00, 00, 00, 00, 00, d2, 01, d1, 01. I guess there is something in the
container that should be skipped.

ffmpeg does not support 24 bits audio, or am I overlooking something ?

TIA for you help.



diff -dupr ffmpeg__orig/libavcodec/adpcm.c ffmpeg/libavcodec/adpcm.c
--- ffmpeg__orig/libavcodec/adpcm.c	2008-02-06 12:37:37.000000000 +0000
+++ ffmpeg/libavcodec/adpcm.c	2008-03-23 22:26:48.000000000 +0000
@@ -1531,6 +1531,32 @@ static int adpcm_decode_frame(AVCodecCon
         samples -= st;
         break;
     }
+    case CODEC_ID_LPCM_S24:
+        if (buf_size < 12 || buf_size % 12 != 0) {
+            av_log(avctx, AV_LOG_ERROR, "buf_size not multiple of 12\n");
+            return -1;
+        }
+//av_log(avctx, AV_LOG_ERROR, "buf_size=%d\n", buf_size);
+        for (i=buf_size/12, n=0; i>=0; i--, n-=12) {
+            int l0, r0, l1, r1;
+/*
+{char ss[256], *s;
+s=ss;
+for (m=0 ; m<12; m++) s+=snprintf(s, 60, "%02x ", src[m]);
+av_log(avctx, AV_LOG_ERROR, "%s\n", ss);
+}
+*/
+            l0 = (((const int8_t *)src)[0]<<16) + (src[1]<<8) + src[8];
+            r0 = (((const int8_t *)src)[2]<<16) + (src[3]<<8) + src[9];
+            l1 = (((const int8_t *)src)[4]<<16) + (src[5]<<8) + src[10];
+            r1 = (((const int8_t *)src)[6]<<16) + (src[7]<<8) + src[11];
+            src+=12;
+            *samples++ = l0 >> 8;
+            *samples++ = r0 >> 8;
+            *samples++ = l1 >> 8;
+            *samples++ = r1 >> 8;
+        }
+        break;
 
     default:
         return -1;
@@ -1600,3 +1626,4 @@ ADPCM_CODEC  (CODEC_ID_ADPCM_SWF, adpcm_
 ADPCM_DECODER(CODEC_ID_ADPCM_THP, adpcm_thp);
 ADPCM_DECODER(CODEC_ID_ADPCM_XA, adpcm_xa);
 ADPCM_CODEC  (CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha);
+ADPCM_DECODER(CODEC_ID_LPCM_S24, dvd_lpcm_24);
diff -dupr ffmpeg__orig/libavcodec/allcodecs.c ffmpeg/libavcodec/allcodecs.c
--- ffmpeg__orig/libavcodec/allcodecs.c	2008-02-06 12:37:37.000000000 +0000
+++ ffmpeg/libavcodec/allcodecs.c	2008-03-23 21:12:31.000000000 +0000
@@ -261,6 +261,7 @@ void avcodec_register_all(void)
     REGISTER_DECODER (ADPCM_THP, adpcm_thp);
     REGISTER_DECODER (ADPCM_XA, adpcm_xa);
     REGISTER_ENCDEC  (ADPCM_YAMAHA, adpcm_yamaha);
+    REGISTER_DECODER (LPCM_S24, dvd_lpcm_24);
 
     /* subtitles */
     REGISTER_ENCDEC  (DVBSUB, dvbsub);
diff -dupr ffmpeg__orig/libavcodec/avcodec.h ffmpeg/libavcodec/avcodec.h
--- ffmpeg__orig/libavcodec/avcodec.h	2008-02-06 12:37:37.000000000 +0000
+++ ffmpeg/libavcodec/avcodec.h	2008-03-23 20:40:49.000000000 +0000
@@ -220,6 +220,7 @@ enum CodecID {
     CODEC_ID_ADPCM_IMA_EA_SEAD,
     CODEC_ID_ADPCM_IMA_EA_EACS,
     CODEC_ID_ADPCM_EA_XAS,
+    CODEC_ID_LPCM_S24,
 
     /* AMR */
     CODEC_ID_AMR_NB= 0x12000,
diff -dupr ffmpeg__orig/libavformat/mpeg.c ffmpeg/libavformat/mpeg.c
--- ffmpeg__orig/libavformat/mpeg.c	2008-02-06 12:37:37.000000000 +0000
+++ ffmpeg/libavformat/mpeg.c	2008-03-23 19:45:32.000000000 +0000
@@ -469,7 +469,7 @@ static int mpegps_read_packet(AVFormatCo
         codec_id = CODEC_ID_DTS;
     } else if (startcode >= 0xa0 && startcode <= 0xaf) {
         type = CODEC_TYPE_AUDIO;
-        codec_id = CODEC_ID_PCM_S16BE;
+        codec_id = CODEC_ID_LPCM_S24;
     } else if (startcode >= 0xb0 && startcode <= 0xbf) {
         type = CODEC_TYPE_AUDIO;
         codec_id = CODEC_ID_MLP;


--
Giuliano.




More information about the ffmpeg-devel mailing list