changeset 2348:d02fb928ca44 libavcodec

pnm parser
author michael
date Fri, 12 Nov 2004 22:55:29 +0000
parents c6280d48be02
children f7f4f06a55c9
files allcodecs.c avcodec.h parser.c pnm.c
diffstat 4 files changed, 103 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/allcodecs.c	Fri Nov 12 09:48:06 2004 +0000
+++ b/allcodecs.c	Fri Nov 12 22:55:29 2004 +0000
@@ -247,6 +247,7 @@
     av_register_codec_parser(&h263_parser);
     av_register_codec_parser(&h264_parser);
     av_register_codec_parser(&mjpeg_parser);
+    av_register_codec_parser(&pnm_parser);
 
     av_register_codec_parser(&mpegaudio_parser);
 #ifdef CONFIG_AC3
--- a/avcodec.h	Fri Nov 12 09:48:06 2004 +0000
+++ b/avcodec.h	Fri Nov 12 22:55:29 2004 +0000
@@ -17,7 +17,7 @@
 
 #define FFMPEG_VERSION_INT     0x000409
 #define FFMPEG_VERSION         "0.4.9-pre1"
-#define LIBAVCODEC_BUILD       4730
+#define LIBAVCODEC_BUILD       4731
 
 #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT
 #define LIBAVCODEC_VERSION     FFMPEG_VERSION
@@ -2152,7 +2152,7 @@
 } AVCodecParserContext;
 
 typedef struct AVCodecParser {
-    int codec_ids[3]; /* several codec IDs are permitted */
+    int codec_ids[5]; /* several codec IDs are permitted */
     int priv_data_size;
     int (*parser_init)(AVCodecParserContext *s);
     int (*parser_parse)(AVCodecParserContext *s, 
@@ -2180,6 +2180,7 @@
 extern AVCodecParser h263_parser;
 extern AVCodecParser h264_parser;
 extern AVCodecParser mjpeg_parser;
+extern AVCodecParser pnm_parser;
 extern AVCodecParser mpegaudio_parser;
 extern AVCodecParser ac3_parser;
 
--- a/parser.c	Fri Nov 12 09:48:06 2004 +0000
+++ b/parser.c	Fri Nov 12 22:55:29 2004 +0000
@@ -38,7 +38,9 @@
     for(parser = av_first_parser; parser != NULL; parser = parser->next) {
         if (parser->codec_ids[0] == codec_id ||
             parser->codec_ids[1] == codec_id ||
-            parser->codec_ids[2] == codec_id)
+            parser->codec_ids[2] == codec_id ||
+            parser->codec_ids[3] == codec_id ||
+            parser->codec_ids[4] == codec_id)
             goto found;
     }
     return NULL;
--- a/pnm.c	Fri Nov 12 09:48:06 2004 +0000
+++ b/pnm.c	Fri Nov 12 22:55:29 2004 +0000
@@ -17,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include "avcodec.h"
+#include "mpegvideo.h" //only for ParseContext
 
 typedef struct PNMContext {
     uint8_t *bytestream;
@@ -65,25 +66,9 @@
     return 0;
 }
 
-static int pnm_decode_frame(AVCodecContext *avctx, 
-                        void *data, int *data_size,
-                        uint8_t *buf, int buf_size)
-{
-    PNMContext * const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame * const p= (AVFrame*)&s->picture;
-    int i, n, linesize, h;
+static int pnm_decode_header(AVCodecContext *avctx, PNMContext * const s){
     char buf1[32];
-    unsigned char *ptr;
-
-    /* special case for last picture */
-    if (buf_size == 0) {
-        return 0;
-    }
-    
-    s->bytestream_start=
-    s->bytestream= buf;
-    s->bytestream_end= buf + buf_size;
+    int h;
 
     pnm_get(s, buf1, sizeof(buf1));
     if (!strcmp(buf1, "P4")) {
@@ -120,6 +105,30 @@
         h /= 3;
         avctx->height = h;
     }
+    return 0;
+}
+
+static int pnm_decode_frame(AVCodecContext *avctx, 
+                        void *data, int *data_size,
+                        uint8_t *buf, int buf_size)
+{
+    PNMContext * const s = avctx->priv_data;
+    AVFrame *picture = data;
+    AVFrame * const p= (AVFrame*)&s->picture;
+    int i, n, linesize, h;
+    unsigned char *ptr;
+
+    /* special case for last picture */
+    if (buf_size == 0) {
+        return 0;
+    }
+    
+    s->bytestream_start=
+    s->bytestream= buf;
+    s->bytestream_end= buf + buf_size;
+    
+    if(pnm_decode_header(avctx, s) < 0)
+        return h;
     
     if(p->data[0])
         avctx->release_buffer(avctx, p);
@@ -492,6 +501,75 @@
 }
 #endif
 
+static int pnm_parse(AVCodecParserContext *s,
+                           AVCodecContext *avctx,
+                           uint8_t **poutbuf, int *poutbuf_size, 
+                           const uint8_t *buf, int buf_size)
+{
+    ParseContext *pc = s->priv_data;
+    PNMContext pnmctx;
+    int next;
+
+    for(; pc->overread>0; pc->overread--){
+        pc->buffer[pc->index++]= pc->buffer[pc->overread_index++];
+    }
+retry:
+    if(pc->index){
+        pnmctx.bytestream_start=
+        pnmctx.bytestream= pc->buffer;
+        pnmctx.bytestream_end= pc->buffer + pc->index;
+    }else{
+        pnmctx.bytestream_start=
+        pnmctx.bytestream= buf;
+        pnmctx.bytestream_end= buf + buf_size;
+    }
+    if(pnm_decode_header(avctx, &pnmctx) < 0){
+        if(pnmctx.bytestream < pnmctx.bytestream_end){
+            if(pc->index){
+                pc->index=0;
+            }else{
+                buf++;
+                buf_size--;
+            }
+            goto retry;
+        }
+#if 0
+        if(pc->index && pc->index*2 + FF_INPUT_BUFFER_PADDING_SIZE < pc->buffer_size && buf_size > pc->index){
+            memcpy(pc->buffer + pc->index, buf, pc->index);
+            pc->index += pc->index;
+            buf += pc->index;
+            buf_size -= pc->index;
+            goto retry;
+        }
+#endif
+        next= END_NOT_FOUND;
+    }else{
+        next= pnmctx.bytestream - pnmctx.bytestream_start 
+            + avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
+        if(pnmctx.bytestream_start!=buf)
+            next-= pc->index;
+        if(next > buf_size)
+            next= END_NOT_FOUND;
+    }
+    
+    if(ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size)<0){
+        *poutbuf = NULL;
+        *poutbuf_size = 0;
+        return buf_size;
+    }
+    *poutbuf = (uint8_t *)buf;
+    *poutbuf_size = buf_size;
+    return next;
+}
+
+AVCodecParser pnm_parser = {
+    { CODEC_ID_PGM, CODEC_ID_PGMYUV, CODEC_ID_PPM, CODEC_ID_PBM},
+    sizeof(ParseContext),
+    NULL,
+    pnm_parse,
+    ff_parse_close,
+};
+
 AVCodec pgm_encoder = {
     "pgm",
     CODEC_TYPE_VIDEO,