blob: ab654614eb3bc08e262f778e0574cd451f9f9cd1 [file] [log] [blame]
Aurelien Jacobsb16560a2007-05-10 22:37:361/*
2 * MJPEG parser
Diego Biurrun406792e2009-01-19 15:46:403 * Copyright (c) 2000, 2001 Fabrice Bellard
Aurelien Jacobsb16560a2007-05-10 22:37:364 * Copyright (c) 2003 Alex Beregszaszi
5 * Copyright (c) 2003-2004 Michael Niedermayer
6 *
Mans Rullgard2912e872011-03-18 17:35:107 * This file is part of Libav.
Aurelien Jacobsb16560a2007-05-10 22:37:368 *
Mans Rullgard2912e872011-03-18 17:35:109 * Libav is free software; you can redistribute it and/or
Aurelien Jacobsb16560a2007-05-10 22:37:3610 * 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 *
Mans Rullgard2912e872011-03-18 17:35:1014 * Libav is distributed in the hope that it will be useful,
Aurelien Jacobsb16560a2007-05-10 22:37:3615 * 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
Mans Rullgard2912e872011-03-18 17:35:1020 * License along with Libav; if not, write to the Free Software
Aurelien Jacobsb16560a2007-05-10 22:37:3621 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24/**
Diego Biurrunba87f082010-04-20 14:45:3425 * @file
Aurelien Jacobsb16560a2007-05-10 22:37:3626 * MJPEG parser.
27 */
28
29#include "parser.h"
30
31
32/**
Diego Biurrun58c42af2011-12-07 12:03:5333 * Find the end of the current frame in the bitstream.
Aurelien Jacobsb16560a2007-05-10 22:37:3634 * @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,
Baptiste Coudurier6b620372009-08-02 08:47:0274 AVCodecContext *avctx,
75 const uint8_t **poutbuf, int *poutbuf_size,
76 const uint8_t *buf, int buf_size)
Aurelien Jacobsb16560a2007-05-10 22:37:3677{
78 ParseContext *pc = s->priv_data;
79 int next;
80
Baptiste Coudurier4546bf42009-08-02 08:46:1181 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
82 next= buf_size;
83 }else{
Baptiste Coudurieree5b26f2009-08-02 08:46:4384 next= find_frame_end(pc, buf, buf_size);
Aurelien Jacobsb16560a2007-05-10 22:37:3685
Baptiste Coudurieree5b26f2009-08-02 08:46:4386 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
87 *poutbuf = NULL;
88 *poutbuf_size = 0;
89 return buf_size;
90 }
Baptiste Coudurier4546bf42009-08-02 08:46:1191 }
Aurelien Jacobsb16560a2007-05-10 22:37:3692
93 *poutbuf = buf;
94 *poutbuf_size = buf_size;
95 return next;
96}
97
98
Diego Elio Pettenòd36beb32011-01-25 21:40:1199AVCodecParser ff_mjpeg_parser = {
Anton Khirnov36ef5362012-08-05 09:11:04100 .codec_ids = { AV_CODEC_ID_MJPEG },
Anton Khirnov5511ad12011-11-02 08:34:41101 .priv_data_size = sizeof(ParseContext),
102 .parser_parse = jpeg_parse,
103 .parser_close = ff_parse_close,
Aurelien Jacobsb16560a2007-05-10 22:37:36104};