]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/lxfdec.c
mp3: Properly use AVCodecContext API
[ffmpeg] / libavformat / lxfdec.c
index 75be218f3d3d1c13c737dcef41bc082216a649be..e25f82e0af33742bf5583da18adb442f37b5191e 100644 (file)
@@ -19,6 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <inttypes.h>
+
 #include "libavutil/intreadwrite.h"
 #include "libavcodec/bytestream.h"
 #include "avformat.h"
@@ -29,7 +31,6 @@
 #define LXF_IDENT               "LEITCH\0"
 #define LXF_IDENT_LENGTH        8
 #define LXF_SAMPLERATE          48000
-#define LXF_MAX_AUDIO_PACKET    (8008*15*4) ///< 15-channel 32-bit NTSC audio frame
 
 static const AVCodecTag lxf_tags[] = {
     { AV_CODEC_ID_MJPEG,       0 },
@@ -45,9 +46,8 @@ static const AVCodecTag lxf_tags[] = {
     { AV_CODEC_ID_NONE,        0 },
 };
 
-typedef struct {
+typedef struct LXFDemuxContext {
     int channels;                       ///< number of audio channels. zero means no audio
-    uint8_t temp[LXF_MAX_AUDIO_PACKET]; ///< temp buffer for de-planarizing the audio data
     int frame_number;                   ///< current video frame
     uint32_t video_format, packet_type, extended_size;
 } LXFDemuxContext;
@@ -130,12 +130,12 @@ static int get_packet_header(AVFormatContext *s)
     version     = bytestream_get_le32(&p);
     header_size = bytestream_get_le32(&p);
     if (version > 1)
-        avpriv_request_sample(s, "Unknown format version %i\n", version);
+        avpriv_request_sample(s, "Unknown format version %"PRIu32"\n", version);
 
     if (header_size < (version ? 72 : 60) ||
         header_size > LXF_MAX_PACKET_HEADER_SIZE ||
         (header_size & 3)) {
-        av_log(s, AV_LOG_ERROR, "Invalid header size 0x%x\n", header_size);
+        av_log(s, AV_LOG_ERROR, "Invalid header size 0x%"PRIx32"\n", header_size);
         return AVERROR_INVALIDDATA;
     }
 
@@ -162,7 +162,7 @@ static int get_packet_header(AVFormatContext *s)
         break;
     case 1:
         //audio
-        if (!(st = s->streams[1])) {
+        if (s->nb_streams < 2) {
             av_log(s, AV_LOG_INFO, "got audio packet, but no audio stream present\n");
             break;
         }
@@ -173,6 +173,8 @@ static int get_packet_header(AVFormatContext *s)
         channels     = bytestream_get_le32(&p);
         track_size   = bytestream_get_le32(&p);
 
+        st = s->streams[1];
+
         //set codec based on specified audio bitdepth
         //we only support tightly packed 16-, 20-, 24- and 32-bit PCM at the moment
         st->codec->bits_per_coded_sample = (audio_format >> 6) & 0x3F;
@@ -183,10 +185,10 @@ static int get_packet_header(AVFormatContext *s)
         }
 
         switch (st->codec->bits_per_coded_sample) {
-        case 16: st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; break;
+        case 16: st->codec->codec_id = AV_CODEC_ID_PCM_S16LE_PLANAR; break;
         case 20: st->codec->codec_id = AV_CODEC_ID_PCM_LXF;   break;
-        case 24: st->codec->codec_id = AV_CODEC_ID_PCM_S24LE; break;
-        case 32: st->codec->codec_id = AV_CODEC_ID_PCM_S32LE; break;
+        case 24: st->codec->codec_id = AV_CODEC_ID_PCM_S24LE_PLANAR; break;
+        case 32: st->codec->codec_id = AV_CODEC_ID_PCM_S32LE_PLANAR; break;
         default:
             av_log(s, AV_LOG_WARNING,
                    "only 16-, 20-, 24- and 32-bit PCM currently supported\n");
@@ -270,7 +272,7 @@ static int lxf_read_header(AVFormatContext *s)
     if ((video_params >> 22) & 1)
         av_log(s, AV_LOG_WARNING, "VBI data not yet supported\n");
 
-    if ((lxf->channels = (disk_params >> 2) & 0xF)) {
+    if ((lxf->channels = 1 << (disk_params >> 4 & 3) + 1)) {
         if (!(st = avformat_new_stream(s, NULL)))
             return AVERROR(ENOMEM);
 
@@ -286,29 +288,10 @@ static int lxf_read_header(AVFormatContext *s)
     return 0;
 }
 
-/**
- * De-planerize the PCM data in lxf->temp
- * FIXME: remove this once support for planar audio is added to libavcodec
- *
- * @param[out] out where to write the de-planerized data to
- * @param[in] bytes the total size of the PCM data
- */
-static void deplanarize(LXFDemuxContext *lxf, AVStream *ast, uint8_t *out, int bytes)
-{
-    int x, y, z, i, bytes_per_sample = ast->codec->bits_per_coded_sample >> 3;
-
-    for (z = i = 0; z < lxf->channels; z++)
-        for (y = 0; y < bytes / bytes_per_sample / lxf->channels; y++)
-            for (x = 0; x < bytes_per_sample; x++, i++)
-                out[x + bytes_per_sample*(z + y*lxf->channels)] = lxf->temp[i];
-}
-
 static int lxf_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     LXFDemuxContext *lxf = s->priv_data;
     AVIOContext   *pb  = s->pb;
-    uint8_t *buf;
-    AVStream *ast = NULL;
     uint32_t stream;
     int ret, ret2;
 
@@ -318,39 +301,27 @@ static int lxf_read_packet(AVFormatContext *s, AVPacket *pkt)
     stream = lxf->packet_type;
 
     if (stream > 1) {
-        av_log(s, AV_LOG_WARNING, "got packet with illegal stream index %u\n", stream);
+        av_log(s, AV_LOG_WARNING,
+               "got packet with illegal stream index %"PRIu32"\n", stream);
         return AVERROR(EAGAIN);
     }
 
-    if (stream == 1 && !(ast = s->streams[1])) {
+    if (stream == 1 && s->nb_streams < 2) {
         av_log(s, AV_LOG_ERROR, "got audio packet without having an audio stream\n");
         return AVERROR_INVALIDDATA;
     }
 
-    //make sure the data fits in the de-planerization buffer
-    if (ast && ret > LXF_MAX_AUDIO_PACKET) {
-        av_log(s, AV_LOG_ERROR, "audio packet too large (%i > %i)\n",
-            ret, LXF_MAX_AUDIO_PACKET);
-        return AVERROR_INVALIDDATA;
-    }
-
     if ((ret2 = av_new_packet(pkt, ret)) < 0)
         return ret2;
 
-    //read non-20-bit audio data into lxf->temp so we can deplanarize it
-    buf = ast && ast->codec->codec_id != AV_CODEC_ID_PCM_LXF ? lxf->temp : pkt->data;
-
-    if ((ret2 = avio_read(pb, buf, ret)) != ret) {
+    if ((ret2 = avio_read(pb, pkt->data, ret)) != ret) {
         av_free_packet(pkt);
         return ret2 < 0 ? ret2 : AVERROR_EOF;
     }
 
     pkt->stream_index = stream;
 
-    if (ast) {
-        if(ast->codec->codec_id != AV_CODEC_ID_PCM_LXF)
-            deplanarize(lxf, ast, pkt->data, ret);
-    } else {
+    if (!stream) {
         //picture type (0 = closed I, 1 = open I, 2 = P, 3 = B)
         if (((lxf->video_format >> 22) & 0x3) < 2)
             pkt->flags |= AV_PKT_FLAG_KEY;