[FFmpeg-cvslog] Merge commit 'f78d360bba6dcfb585847a49a84e89c25950fbdb'

James Almer git at videolan.org
Tue Apr 4 20:50:06 EEST 2017


ffmpeg | branch: master | James Almer <jamrial at gmail.com> | Tue Apr  4 14:34:52 2017 -0300| [fddd6af45cfdb228cd34c36210a8afd39757a6c8] | committer: James Almer

Merge commit 'f78d360bba6dcfb585847a49a84e89c25950fbdb'

* commit 'f78d360bba6dcfb585847a49a84e89c25950fbdb':
  examples/decode_video: use a parser for splitting the input

Merged-by: James Almer <jamrial at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fddd6af45cfdb228cd34c36210a8afd39757a6c8
---

 doc/examples/decode_video.c | 110 ++++++++++++++++++++++----------------------
 1 file changed, 56 insertions(+), 54 deletions(-)

diff --git a/doc/examples/decode_video.c b/doc/examples/decode_video.c
index dd1177b..980add3 100644
--- a/doc/examples/decode_video.c
+++ b/doc/examples/decode_video.c
@@ -48,43 +48,47 @@ static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
     fclose(f);
 }
 
-static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
-                              AVFrame *frame, int *frame_count, AVPacket *pkt, int last)
+static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
+                   const char *filename)
 {
-    int len, got_frame;
     char buf[1024];
-
-    len = avcodec_decode_video2(avctx, frame, &got_frame, pkt);
-    if (len < 0) {
-        fprintf(stderr, "Error while decoding frame %d\n", *frame_count);
-        return len;
-    }
-    if (got_frame) {
-        printf("Saving %sframe %3d\n", last ? "last " : "", *frame_count);
-        fflush(stdout);
-
-        /* the picture is allocated by the decoder, no need to free it */
-        snprintf(buf, sizeof(buf), outfilename, *frame_count);
-        pgm_save(frame->data[0], frame->linesize[0],
-                 frame->width, frame->height, buf);
-        (*frame_count)++;
+    int ret, got_picture;
+
+    while (pkt->size > 0) {
+        ret = avcodec_decode_video2(dec_ctx, frame, &got_picture, pkt);
+        if (ret < 0) {
+            fprintf(stderr, "Error while decoding frame %d\n", dec_ctx->frame_number);
+            exit(1);
+        }
+        if (got_picture) {
+            printf("saving frame %3d\n", dec_ctx->frame_number);
+            fflush(stdout);
+
+            /* the picture is allocated by the decoder. no need to
+               free it */
+            snprintf(buf, sizeof(buf), filename, dec_ctx->frame_number);
+            pgm_save(frame->data[0], frame->linesize[0],
+                     frame->width, frame->height, buf);
+        }
+        if (pkt->data) {
+            pkt->size -= ret;
+            pkt->data += ret;
+        }
     }
-    if (pkt->data) {
-        pkt->size -= len;
-        pkt->data += len;
-    }
-    return 0;
 }
 
 int main(int argc, char **argv)
 {
     const char *filename, *outfilename;
     const AVCodec *codec;
+    AVCodecParserContext *parser;
     AVCodecContext *c= NULL;
-    int frame_count;
     FILE *f;
     AVFrame *frame;
     uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
+    uint8_t *data;
+    size_t   data_size;
+    int ret;
     AVPacket avpkt;
 
     if (argc <= 2) {
@@ -108,15 +112,18 @@ int main(int argc, char **argv)
         exit(1);
     }
 
+    parser = av_parser_init(codec->id);
+    if (!parser) {
+        fprintf(stderr, "parser not found\n");
+        exit(1);
+    }
+
     c = avcodec_alloc_context3(codec);
     if (!c) {
         fprintf(stderr, "Could not allocate video codec context\n");
         exit(1);
     }
 
-    if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
-        c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
-
     /* For some codecs, such as msmpeg4 and mpeg4, width and height
        MUST be initialized there because this information is not
        available in the bitstream. */
@@ -139,42 +146,37 @@ int main(int argc, char **argv)
         exit(1);
     }
 
-    frame_count = 0;
-    for (;;) {
-        avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
-        if (avpkt.size == 0)
+    while (!feof(f)) {
+        /* read raw data from the input file */
+        data_size = fread(inbuf, 1, INBUF_SIZE, f);
+        if (!data_size)
             break;
 
-        /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
-           and this is the only method to use them because you cannot
-           know the compressed data size before analysing it.
-
-           BUT some other codecs (msmpeg4, mpeg4) are inherently frame
-           based, so you must call them with all the data for one
-           frame exactly. You must also initialize 'width' and
-           'height' before initializing them. */
-
-        /* NOTE2: some codecs allow the raw parameters (frame size,
-           sample rate) to be changed at any frame. We handle this, so
-           you should also take care of it */
-
-        /* here, we use a stream based decoder (mpeg1video), so we
-           feed decoder and see if it could decode a frame */
-        avpkt.data = inbuf;
-        while (avpkt.size > 0)
-            if (decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 0) < 0)
+        /* use the parser to split the data into frames */
+        data = inbuf;
+        while (data_size > 0) {
+            ret = av_parser_parse2(parser, c, &avpkt.data, &avpkt.size,
+                                   data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
+            if (ret < 0) {
+                fprintf(stderr, "Error while parsing\n");
                 exit(1);
-    }
+            }
+            data      += ret;
+            data_size -= ret;
+
+            if (avpkt.size)
+                decode(c, frame, &avpkt, outfilename);
+         }
+     }
 
-    /* Some codecs, such as MPEG, transmit the I- and P-frame with a
-       latency of one frame. You must do the following to have a
-       chance to get the last frame of the video. */
+    /* flush the decoder */
     avpkt.data = NULL;
     avpkt.size = 0;
-    decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 1);
+    decode(c, frame, &avpkt, outfilename);
 
     fclose(f);
 
+    av_parser_close(parser);
     avcodec_free_context(&c);
     av_frame_free(&frame);
 


======================================================================

diff --cc doc/examples/decode_video.c
index dd1177b,4c1068b..980add3
--- a/doc/examples/decode_video.c
+++ b/doc/examples/decode_video.c
@@@ -48,43 -50,45 +48,47 @@@ static void pgm_save(unsigned char *buf
      fclose(f);
  }
  
- static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
-                               AVFrame *frame, int *frame_count, AVPacket *pkt, int last)
+ static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
+                    const char *filename)
  {
-     int len, got_frame;
      char buf[1024];
- 
-     len = avcodec_decode_video2(avctx, frame, &got_frame, pkt);
-     if (len < 0) {
-         fprintf(stderr, "Error while decoding frame %d\n", *frame_count);
-         return len;
-     }
-     if (got_frame) {
-         printf("Saving %sframe %3d\n", last ? "last " : "", *frame_count);
-         fflush(stdout);
- 
-         /* the picture is allocated by the decoder, no need to free it */
-         snprintf(buf, sizeof(buf), outfilename, *frame_count);
-         pgm_save(frame->data[0], frame->linesize[0],
-                  frame->width, frame->height, buf);
-         (*frame_count)++;
+     int ret, got_picture;
+ 
+     while (pkt->size > 0) {
+         ret = avcodec_decode_video2(dec_ctx, frame, &got_picture, pkt);
+         if (ret < 0) {
+             fprintf(stderr, "Error while decoding frame %d\n", dec_ctx->frame_number);
+             exit(1);
+         }
+         if (got_picture) {
+             printf("saving frame %3d\n", dec_ctx->frame_number);
+             fflush(stdout);
+ 
+             /* the picture is allocated by the decoder. no need to
+                free it */
+             snprintf(buf, sizeof(buf), filename, dec_ctx->frame_number);
+             pgm_save(frame->data[0], frame->linesize[0],
+                      frame->width, frame->height, buf);
+         }
 -        pkt->size -= ret;
 -        pkt->data += ret;
++        if (pkt->data) {
++            pkt->size -= ret;
++            pkt->data += ret;
++        }
      }
-     if (pkt->data) {
-         pkt->size -= len;
-         pkt->data += len;
-     }
-     return 0;
  }
  
  int main(int argc, char **argv)
  {
      const char *filename, *outfilename;
      const AVCodec *codec;
+     AVCodecParserContext *parser;
      AVCodecContext *c= NULL;
-     int frame_count;
      FILE *f;
 -    AVFrame *picture;
 +    AVFrame *frame;
      uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
+     uint8_t *data;
+     size_t   data_size;
+     int ret;
      AVPacket avpkt;
  
      if (argc <= 2) {
@@@ -108,15 -112,15 +112,18 @@@
          exit(1);
      }
  
+     parser = av_parser_init(codec->id);
+     if (!parser) {
+         fprintf(stderr, "parser not found\n");
+         exit(1);
+     }
+ 
      c = avcodec_alloc_context3(codec);
 -    picture = av_frame_alloc();
 +    if (!c) {
 +        fprintf(stderr, "Could not allocate video codec context\n");
 +        exit(1);
 +    }
  
-     if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
-         c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
- 
      /* For some codecs, such as msmpeg4 and mpeg4, width and height
         MUST be initialized there because this information is not
         available in the bitstream. */
@@@ -139,44 -137,39 +146,39 @@@
          exit(1);
      }
  
-     frame_count = 0;
-     for (;;) {
-         avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
-         if (avpkt.size == 0)
+     while (!feof(f)) {
+         /* read raw data from the input file */
+         data_size = fread(inbuf, 1, INBUF_SIZE, f);
+         if (!data_size)
              break;
  
-         /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
-            and this is the only method to use them because you cannot
-            know the compressed data size before analysing it.
- 
-            BUT some other codecs (msmpeg4, mpeg4) are inherently frame
-            based, so you must call them with all the data for one
-            frame exactly. You must also initialize 'width' and
-            'height' before initializing them. */
- 
-         /* NOTE2: some codecs allow the raw parameters (frame size,
-            sample rate) to be changed at any frame. We handle this, so
-            you should also take care of it */
- 
-         /* here, we use a stream based decoder (mpeg1video), so we
-            feed decoder and see if it could decode a frame */
-         avpkt.data = inbuf;
-         while (avpkt.size > 0)
-             if (decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 0) < 0)
+         /* use the parser to split the data into frames */
+         data = inbuf;
+         while (data_size > 0) {
+             ret = av_parser_parse2(parser, c, &avpkt.data, &avpkt.size,
+                                    data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
+             if (ret < 0) {
+                 fprintf(stderr, "Error while parsing\n");
                  exit(1);
-     }
+             }
+             data      += ret;
+             data_size -= ret;
+ 
+             if (avpkt.size)
 -                decode(c, picture, &avpkt, outfilename);
 -        }
 -    }
++                decode(c, frame, &avpkt, outfilename);
++         }
++     }
  
-     /* Some codecs, such as MPEG, transmit the I- and P-frame with a
-        latency of one frame. You must do the following to have a
-        chance to get the last frame of the video. */
+     /* flush the decoder */
      avpkt.data = NULL;
      avpkt.size = 0;
-     decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 1);
 -    decode(c, picture, &avpkt, outfilename);
++    decode(c, frame, &avpkt, outfilename);
  
      fclose(f);
  
+     av_parser_close(parser);
      avcodec_free_context(&c);
 -    av_frame_free(&picture);
 +    av_frame_free(&frame);
  
      return 0;
  }



More information about the ffmpeg-cvslog mailing list