LCOV - code coverage report
Current view: top level - libavcodec - mpeg4video_parser.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 66 68 97.1 %
Date: 2017-12-14 01:15:32 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  * MPEG-4 video frame extraction
       3             :  * Copyright (c) 2003 Fabrice Bellard
       4             :  * Copyright (c) 2003 Michael Niedermayer
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public
      10             :  * License as published by the Free Software Foundation; either
      11             :  * version 2.1 of the License, or (at your option) any later version.
      12             :  *
      13             :  * FFmpeg is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :  * Lesser General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU Lesser General Public
      19             :  * License along with FFmpeg; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : #define UNCHECKED_BITSTREAM_READER 1
      24             : 
      25             : #include "internal.h"
      26             : #include "parser.h"
      27             : #include "mpegvideo.h"
      28             : #include "mpeg4video.h"
      29             : #include "mpeg4video_parser.h"
      30             : 
      31             : struct Mp4vParseContext {
      32             :     ParseContext pc;
      33             :     Mpeg4DecContext dec_ctx;
      34             :     int first_picture;
      35             : };
      36             : 
      37        8238 : int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
      38             : {
      39             :     int vop_found, i;
      40             :     uint32_t state;
      41             : 
      42        8238 :     vop_found = pc->frame_start_found;
      43        8238 :     state     = pc->state;
      44             : 
      45        8238 :     i = 0;
      46        8238 :     if (!vop_found) {
      47        8438 :         for (i = 0; i < buf_size; i++) {
      48        8436 :             state = (state << 8) | buf[i];
      49        8436 :             if (state == 0x1B6) {
      50        1085 :                 i++;
      51        1085 :                 vop_found = 1;
      52        1085 :                 break;
      53             :             }
      54             :         }
      55             :     }
      56             : 
      57        8238 :     if (vop_found) {
      58             :         /* EOF considered as end of frame */
      59        8236 :         if (buf_size == 0)
      60          24 :             return 0;
      61     8516208 :         for (; i < buf_size; i++) {
      62     8509069 :             state = (state << 8) | buf[i];
      63     8509069 :             if ((state & 0xFFFFFF00) == 0x100) {
      64        1073 :                 pc->frame_start_found = 0;
      65        1073 :                 pc->state             = -1;
      66        1073 :                 return i - 3;
      67             :             }
      68             :         }
      69             :     }
      70        7141 :     pc->frame_start_found = vop_found;
      71        7141 :     pc->state             = state;
      72        7141 :     return END_NOT_FOUND;
      73             : }
      74             : 
      75             : /* XXX: make it use less memory */
      76        3549 : static int mpeg4_decode_header(AVCodecParserContext *s1, AVCodecContext *avctx,
      77             :                                const uint8_t *buf, int buf_size)
      78             : {
      79        3549 :     struct Mp4vParseContext *pc = s1->priv_data;
      80        3549 :     Mpeg4DecContext *dec_ctx = &pc->dec_ctx;
      81        3549 :     MpegEncContext *s = &dec_ctx->m;
      82        3549 :     GetBitContext gb1, *gb = &gb1;
      83             :     int ret;
      84             : 
      85        3549 :     s->avctx               = avctx;
      86        3549 :     s->current_picture_ptr = &s->current_picture;
      87             : 
      88        3549 :     if (avctx->extradata_size && pc->first_picture) {
      89         241 :         init_get_bits(gb, avctx->extradata, avctx->extradata_size * 8);
      90         241 :         ret = ff_mpeg4_decode_picture_header(dec_ctx, gb);
      91         241 :         if (ret < -1)
      92           0 :             av_log(avctx, AV_LOG_WARNING, "Failed to parse extradata\n");
      93             :     }
      94             : 
      95        3549 :     init_get_bits(gb, buf, 8 * buf_size);
      96        3549 :     ret = ff_mpeg4_decode_picture_header(dec_ctx, gb);
      97        7034 :     if (s->width && (!avctx->width || !avctx->height ||
      98        6970 :                      !avctx->coded_width || !avctx->coded_height)) {
      99          12 :         ret = ff_set_dimensions(avctx, s->width, s->height);
     100          12 :         if (ret < 0)
     101           0 :             return ret;
     102             :     }
     103        3549 :     if((s1->flags & PARSER_FLAG_USE_CODEC_TS) && s->avctx->time_base.den>0 && ret>=0){
     104             :         av_assert1(s1->pts == AV_NOPTS_VALUE);
     105             :         av_assert1(s1->dts == AV_NOPTS_VALUE);
     106             : 
     107         874 :         s1->pts = av_rescale_q(s->time, (AVRational){1, s->avctx->time_base.den}, (AVRational){1, 1200000});
     108             :     }
     109             : 
     110        3549 :     s1->pict_type     = s->pict_type;
     111        3549 :     pc->first_picture = 0;
     112        3549 :     return ret;
     113             : }
     114             : 
     115         336 : static av_cold int mpeg4video_parse_init(AVCodecParserContext *s)
     116             : {
     117         336 :     struct Mp4vParseContext *pc = s->priv_data;
     118             : 
     119         336 :     ff_mpeg4videodec_static_init();
     120             : 
     121         336 :     pc->first_picture           = 1;
     122         336 :     pc->dec_ctx.m.quant_precision     = 5;
     123         336 :     pc->dec_ctx.m.slice_context_count = 1;
     124         336 :     pc->dec_ctx.showed_packed_warning = 1;
     125         336 :     return 0;
     126             : }
     127             : 
     128       10690 : static int mpeg4video_parse(AVCodecParserContext *s,
     129             :                             AVCodecContext *avctx,
     130             :                             const uint8_t **poutbuf, int *poutbuf_size,
     131             :                             const uint8_t *buf, int buf_size)
     132             : {
     133       10690 :     ParseContext *pc = s->priv_data;
     134             :     int next;
     135             : 
     136       10690 :     if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
     137        2452 :         next = buf_size;
     138             :     } else {
     139        8238 :         next = ff_mpeg4_find_frame_end(pc, buf, buf_size);
     140             : 
     141        8238 :         if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
     142        7141 :             *poutbuf      = NULL;
     143        7141 :             *poutbuf_size = 0;
     144        7141 :             return buf_size;
     145             :         }
     146             :     }
     147        3549 :     mpeg4_decode_header(s, avctx, buf, buf_size);
     148             : 
     149        3549 :     *poutbuf      = buf;
     150        3549 :     *poutbuf_size = buf_size;
     151        3549 :     return next;
     152             : }
     153             : 
     154             : AVCodecParser ff_mpeg4video_parser = {
     155             :     .codec_ids      = { AV_CODEC_ID_MPEG4 },
     156             :     .priv_data_size = sizeof(struct Mp4vParseContext),
     157             :     .parser_init    = mpeg4video_parse_init,
     158             :     .parser_parse   = mpeg4video_parse,
     159             :     .parser_close   = ff_parse_close,
     160             :     .split          = ff_mpeg4video_split,
     161             : };

Generated by: LCOV version 1.13