1/* 2 * MJPEG parser 3 * Copyright (c) 2000, 2001 Fabrice Bellard 4 * Copyright (c) 2003 Alex Beregszaszi 5 * Copyright (c) 2003-2004 Michael Niedermayer 6 * 7 * This file is part of FFmpeg. 8 * 9 * FFmpeg is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * FFmpeg is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with FFmpeg; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 24/** 25 * @file 26 * MJPEG parser. 27 */ 28 29#include "parser.h" 30 31 32/** 33 * finds the end of the current frame in the bitstream. 34 * @return the position of the first byte of the next frame, or -1 35 */ 36static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){ 37 int vop_found, i; 38 uint16_t state; 39 40 vop_found= pc->frame_start_found; 41 state= pc->state; 42 43 i=0; 44 if(!vop_found){ 45 for(i=0; i<buf_size; i++){ 46 state= (state<<8) | buf[i]; 47 if(state == 0xFFD8){ 48 i++; 49 vop_found=1; 50 break; 51 } 52 } 53 } 54 55 if(vop_found){ 56 /* EOF considered as end of frame */ 57 if (buf_size == 0) 58 return 0; 59 for(; i<buf_size; i++){ 60 state= (state<<8) | buf[i]; 61 if(state == 0xFFD8){ 62 pc->frame_start_found=0; 63 pc->state=0; 64 return i-1; 65 } 66 } 67 } 68 pc->frame_start_found= vop_found; 69 pc->state= state; 70 return END_NOT_FOUND; 71} 72 73static int jpeg_parse(AVCodecParserContext *s, 74 AVCodecContext *avctx, 75 const uint8_t **poutbuf, int *poutbuf_size, 76 const uint8_t *buf, int buf_size) 77{ 78 ParseContext *pc = s->priv_data; 79 int next; 80 81 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ 82 next= buf_size; 83 }else{ 84 next= find_frame_end(pc, buf, buf_size); 85 86 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { 87 *poutbuf = NULL; 88 *poutbuf_size = 0; 89 return buf_size; 90 } 91 } 92 93 *poutbuf = buf; 94 *poutbuf_size = buf_size; 95 return next; 96} 97 98 99AVCodecParser mjpeg_parser = { 100 { CODEC_ID_MJPEG }, 101 sizeof(ParseContext), 102 NULL, 103 jpeg_parse, 104 ff_parse_close, 105}; 106