]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/parser.c
adds some useful comments after some of the #else, #elseif,
[ffmpeg] / libavcodec / parser.c
index 1977dd4943f77ed9eb4048e2928bd54605fb45af..c82744bdffbfa289debb7afbb5100a34718deceb 100644 (file)
@@ -3,18 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard.
  * Copyright (c) 2003 Michael Niedermayer.
  *
- * This library is free software; you can redistribute it and/or
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * version 2.1 of the License, or (at your option) any later version.
  *
- * This library is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avcodec.h"
@@ -69,8 +71,29 @@ AVCodecParserContext *av_parser_init(int codec_id)
     return s;
 }
 
-/* NOTE: buf_size == 0 is used to signal EOF so that the last frame
-   can be returned if necessary */
+/**
+ *
+ * @param buf           input
+ * @param buf_size      input length, to signal EOF, this should be 0 (so that the last frame can be output)
+ * @param pts           input presentation timestamp
+ * @param dts           input decoding timestamp
+ * @param poutbuf       will contain a pointer to the first byte of the output frame
+ * @param poutbuf_size  will contain the length of the output frame
+ * @return the number of bytes of the input bitstream used
+ *
+ * Example:
+ * @code
+ *   while(in_len){
+ *       len = av_parser_parse(myparser, AVCodecContext, &data, &size,
+ *                                       in_data, in_len,
+ *                                       pts, dts);
+ *       in_data += len;
+ *       in_len  -= len;
+ *
+ *       decode_frame(data, size);
+ *   }
+ * @endcode
+ */
 int av_parser_parse(AVCodecParserContext *s,
                     AVCodecContext *avctx,
                     uint8_t **poutbuf, int *poutbuf_size,
@@ -145,6 +168,7 @@ int av_parser_parse(AVCodecParserContext *s,
 /**
  *
  * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed
+ * @deprecated use AVBitstreamFilter
  */
 int av_parser_change(AVCodecParserContext *s,
                      AVCodecContext *avctx,
@@ -297,6 +321,7 @@ static const int frame_rate_tab[16] = {
     25025,
 };
 
+#ifdef CONFIG_MPEGVIDEO_PARSER
 //FIXME move into mpeg12.c
 static void mpegvideo_extract_headers(AVCodecParserContext *s,
                                       AVCodecContext *avctx,
@@ -304,7 +329,7 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
 {
     ParseContext1 *pc = s->priv_data;
     const uint8_t *buf_end;
-    int32_t start_code;
+    uint32_t start_code;
     int frame_rate_index, ext_type, bytes_left;
     int frame_rate_ext_n, frame_rate_ext_d;
     int picture_structure, top_field_first, repeat_first_field, progressive_frame;
@@ -449,6 +474,7 @@ static int mpegvideo_split(AVCodecContext *avctx,
     }
     return 0;
 }
+#endif /* CONFIG_MPEGVIDEO_PARSER */
 
 void ff_parse_close(AVCodecParserContext *s)
 {
@@ -467,6 +493,7 @@ static void parse1_close(AVCodecParserContext *s)
 
 /*************************/
 
+#ifdef CONFIG_MPEG4VIDEO_PARSER
 /* used by parser */
 /* XXX: make it use less memory */
 static int av_mpeg4_decode_header(AVCodecParserContext *s1,
@@ -532,7 +559,9 @@ static int mpeg4video_parse(AVCodecParserContext *s,
     *poutbuf_size = buf_size;
     return next;
 }
+#endif
 
+#ifdef CONFIG_CAVSVIDEO_PARSER
 static int cavsvideo_parse(AVCodecParserContext *s,
                            AVCodecContext *avctx,
                            uint8_t **poutbuf, int *poutbuf_size,
@@ -556,6 +585,7 @@ static int cavsvideo_parse(AVCodecParserContext *s,
     *poutbuf_size = buf_size;
     return next;
 }
+#endif /* CONFIG_CAVSVIDEO_PARSER */
 
 static int mpeg4video_split(AVCodecContext *avctx,
                            const uint8_t *buf, int buf_size)
@@ -573,6 +603,7 @@ static int mpeg4video_split(AVCodecContext *avctx,
 
 /*************************/
 
+#ifdef CONFIG_MPEGAUDIO_PARSER
 typedef struct MpegAudioParseContext {
     uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE];    /* input buffer */
     uint8_t *inbuf_ptr;
@@ -626,9 +657,7 @@ static int mpegaudio_parse(AVCodecParserContext *s1,
             }
             /* no header seen : find one. We need at least MPA_HEADER_SIZE
                bytes to parse it */
-            len = MPA_HEADER_SIZE - len;
-            if (len > buf_size)
-                len = buf_size;
+            len = FFMIN(MPA_HEADER_SIZE - len, buf_size);
             if (len > 0) {
                 memcpy(s->inbuf_ptr, buf_ptr, len);
                 buf_ptr += len;
@@ -728,14 +757,25 @@ static int mpegaudio_parse(AVCodecParserContext *s1,
         if (len < s->frame_size) {
             if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE)
                 s->frame_size = MPA_MAX_CODED_FRAME_SIZE;
-            len = s->frame_size - len;
-            if (len > buf_size)
-                len = buf_size;
+            len = FFMIN(s->frame_size - len, buf_size);
             memcpy(s->inbuf_ptr, buf_ptr, len);
             buf_ptr += len;
             s->inbuf_ptr += len;
             buf_size -= len;
         }
+
+        if(s->frame_size > 0 && buf_ptr - buf == s->inbuf_ptr - s->inbuf
+           && buf_size + buf_ptr - buf >= s->frame_size){
+            if(s->header_count > 0){
+                *poutbuf = buf;
+                *poutbuf_size = s->frame_size;
+            }
+            buf_ptr = buf + s->frame_size;
+            s->inbuf_ptr = s->inbuf;
+            s->frame_size = 0;
+            break;
+        }
+
         //    next_data:
         if (s->frame_size > 0 &&
             (s->inbuf_ptr - s->inbuf) >= s->frame_size) {
@@ -750,7 +790,9 @@ static int mpegaudio_parse(AVCodecParserContext *s1,
     }
     return buf_ptr - buf;
 }
+#endif /* CONFIG_MPEGAUDIO_PARSER */
 
+#if defined(CONFIG_AC3_PARSER) || defined(CONFIG_AAC_PARSER)
 /* also used for ADTS AAC */
 typedef struct AC3ParseContext {
     uint8_t *inbuf_ptr;
@@ -764,6 +806,7 @@ typedef struct AC3ParseContext {
 #define AC3_HEADER_SIZE 7
 #define AAC_HEADER_SIZE 7
 
+#ifdef CONFIG_AC3_PARSER
 static const int ac3_sample_rates[4] = {
     48000, 44100, 32000, 0
 };
@@ -818,16 +861,20 @@ static const int ac3_bitrates[64] = {
 static const int ac3_channels[8] = {
     2, 1, 2, 3, 3, 4, 4, 5
 };
+#endif /* CONFIG_AC3_PARSER */
 
-static int aac_sample_rates[16] = {
+#ifdef CONFIG_AAC_PARSER
+static const int aac_sample_rates[16] = {
     96000, 88200, 64000, 48000, 44100, 32000,
     24000, 22050, 16000, 12000, 11025, 8000, 7350
 };
 
-static int aac_channels[8] = {
+static const int aac_channels[8] = {
     0, 1, 2, 3, 4, 5, 6, 8
 };
+#endif
 
+#ifdef CONFIG_AC3_PARSER
 static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate,
                     int *bit_rate, int *samples)
 {
@@ -866,7 +913,9 @@ static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate,
 
     return ac3_frame_sizes[frmsizecod][fscod] * 2;
 }
+#endif /* CONFIG_AC3_PARSER */
 
+#ifdef CONFIG_AAC_PARSER
 static int aac_sync(const uint8_t *buf, int *channels, int *sample_rate,
                     int *bit_rate, int *samples)
 {
@@ -906,7 +955,9 @@ static int aac_sync(const uint8_t *buf, int *channels, int *sample_rate,
 
     return size;
 }
+#endif /* CONFIG_AAC_PARSER */
 
+#ifdef CONFIG_AC3_PARSER
 static int ac3_parse_init(AVCodecParserContext *s1)
 {
     AC3ParseContext *s = s1->priv_data;
@@ -915,7 +966,9 @@ static int ac3_parse_init(AVCodecParserContext *s1)
     s->sync = ac3_sync;
     return 0;
 }
+#endif
 
+#ifdef CONFIG_AAC_PARSER
 static int aac_parse_init(AVCodecParserContext *s1)
 {
     AC3ParseContext *s = s1->priv_data;
@@ -924,6 +977,7 @@ static int aac_parse_init(AVCodecParserContext *s1)
     s->sync = aac_sync;
     return 0;
 }
+#endif
 
 /* also used for ADTS AAC */
 static int ac3_parse(AVCodecParserContext *s1,
@@ -992,7 +1046,9 @@ static int ac3_parse(AVCodecParserContext *s1,
     }
     return buf_ptr - buf;
 }
+#endif /* CONFIG_AC3_PARSER || CONFIG_AAC_PARSER */
 
+#ifdef CONFIG_MPEGVIDEO_PARSER
 AVCodecParser mpegvideo_parser = {
     { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO },
     sizeof(ParseContext1),
@@ -1001,7 +1057,8 @@ AVCodecParser mpegvideo_parser = {
     parse1_close,
     mpegvideo_split,
 };
-
+#endif
+#ifdef CONFIG_MPEG4VIDEO_PARSER
 AVCodecParser mpeg4video_parser = {
     { CODEC_ID_MPEG4 },
     sizeof(ParseContext1),
@@ -1010,7 +1067,8 @@ AVCodecParser mpeg4video_parser = {
     parse1_close,
     mpeg4video_split,
 };
-
+#endif
+#ifdef CONFIG_CAVSVIDEO_PARSER
 AVCodecParser cavsvideo_parser = {
     { CODEC_ID_CAVS },
     sizeof(ParseContext1),
@@ -1019,7 +1077,8 @@ AVCodecParser cavsvideo_parser = {
     parse1_close,
     mpeg4video_split,
 };
-
+#endif
+#ifdef CONFIG_MPEGAUDIO_PARSER
 AVCodecParser mpegaudio_parser = {
     { CODEC_ID_MP2, CODEC_ID_MP3 },
     sizeof(MpegAudioParseContext),
@@ -1027,7 +1086,8 @@ AVCodecParser mpegaudio_parser = {
     mpegaudio_parse,
     NULL,
 };
-
+#endif
+#ifdef CONFIG_AC3_PARSER
 AVCodecParser ac3_parser = {
     { CODEC_ID_AC3 },
     sizeof(AC3ParseContext),
@@ -1035,7 +1095,8 @@ AVCodecParser ac3_parser = {
     ac3_parse,
     NULL,
 };
-
+#endif
+#ifdef CONFIG_AAC_PARSER
 AVCodecParser aac_parser = {
     { CODEC_ID_AAC },
     sizeof(AC3ParseContext),
@@ -1043,3 +1104,4 @@ AVCodecParser aac_parser = {
     ac3_parse,
     NULL,
 };
+#endif