Mercurial > libavcodec.hg
annotate pnm.c @ 12525:7c0dbd8eb53a libavcodec
Improve error concealment of lost frames
If a frame is lost, replace it with data from the previous valid frame.
| author | darkshikari |
|---|---|
| date | Mon, 27 Sep 2010 04:43:41 +0000 |
| parents | ffb3668ff7af |
| children |
| rev | line source |
|---|---|
| 4978 | 1 /* |
| 2 * PNM image format | |
|
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
7865
diff
changeset
|
3 * Copyright (c) 2002, 2003 Fabrice Bellard |
| 4978 | 4 * |
| 5 * This file is part of FFmpeg. | |
| 6 * | |
| 7 * FFmpeg is free software; you can redistribute it and/or | |
| 8 * modify it under the terms of the GNU Lesser General Public | |
| 9 * License as published by the Free Software Foundation; either | |
| 10 * version 2.1 of the License, or (at your option) any later version. | |
| 11 * | |
| 12 * FFmpeg is distributed in the hope that it will be useful, | |
| 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 * Lesser General Public License for more details. | |
| 16 * | |
| 17 * You should have received a copy of the GNU Lesser General Public | |
| 18 * License along with FFmpeg; if not, write to the Free Software | |
| 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 20 */ | |
|
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
21 |
|
12372
914f484bb476
Remove use of the deprecated function avcodec_check_dimensions(), use
stefano
parents:
10612
diff
changeset
|
22 #include "libavcore/imgutils.h" |
| 4978 | 23 #include "avcodec.h" |
| 24 #include "pnm.h" | |
| 25 | |
| 26 static inline int pnm_space(int c) | |
| 27 { | |
| 6750 | 28 return c == ' ' || c == '\n' || c == '\r' || c == '\t'; |
| 4978 | 29 } |
| 30 | |
| 31 static void pnm_get(PNMContext *sc, char *str, int buf_size) | |
| 32 { | |
| 33 char *s; | |
| 34 int c; | |
| 35 | |
| 36 /* skip spaces and comments */ | |
|
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
37 for (;;) { |
| 4978 | 38 c = *sc->bytestream++; |
| 39 if (c == '#') { | |
|
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
40 do { |
| 4978 | 41 c = *sc->bytestream++; |
| 42 } while (c != '\n' && sc->bytestream < sc->bytestream_end); | |
| 43 } else if (!pnm_space(c)) { | |
| 44 break; | |
| 45 } | |
| 46 } | |
| 47 | |
| 48 s = str; | |
| 49 while (sc->bytestream < sc->bytestream_end && !pnm_space(c)) { | |
| 50 if ((s - str) < buf_size - 1) | |
| 51 *s++ = c; | |
| 52 c = *sc->bytestream++; | |
| 53 } | |
| 54 *s = '\0'; | |
| 55 } | |
| 56 | |
|
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
57 int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) |
|
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
58 { |
| 4978 | 59 char buf1[32], tuple_type[32]; |
| 60 int h, w, depth, maxval; | |
| 61 | |
| 62 pnm_get(s, buf1, sizeof(buf1)); | |
| 10612 | 63 s->type= buf1[1]-'0'; |
| 64 if(buf1[0] != 'P') | |
| 65 return -1; | |
| 66 | |
| 67 if (s->type==1 || s->type==4) { | |
| 4978 | 68 avctx->pix_fmt = PIX_FMT_MONOWHITE; |
| 10612 | 69 } else if (s->type==2 || s->type==5) { |
| 4978 | 70 if (avctx->codec_id == CODEC_ID_PGMYUV) |
| 71 avctx->pix_fmt = PIX_FMT_YUV420P; | |
| 72 else | |
| 73 avctx->pix_fmt = PIX_FMT_GRAY8; | |
| 10612 | 74 } else if (s->type==3 || s->type==6) { |
| 4978 | 75 avctx->pix_fmt = PIX_FMT_RGB24; |
| 10612 | 76 } else if (s->type==7) { |
|
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
77 w = -1; |
|
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
78 h = -1; |
| 4978 | 79 maxval = -1; |
|
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
80 depth = -1; |
| 4978 | 81 tuple_type[0] = '\0'; |
|
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
82 for (;;) { |
| 4978 | 83 pnm_get(s, buf1, sizeof(buf1)); |
| 84 if (!strcmp(buf1, "WIDTH")) { | |
| 85 pnm_get(s, buf1, sizeof(buf1)); | |
| 86 w = strtol(buf1, NULL, 10); | |
| 87 } else if (!strcmp(buf1, "HEIGHT")) { | |
| 88 pnm_get(s, buf1, sizeof(buf1)); | |
| 89 h = strtol(buf1, NULL, 10); | |
| 90 } else if (!strcmp(buf1, "DEPTH")) { | |
| 91 pnm_get(s, buf1, sizeof(buf1)); | |
| 92 depth = strtol(buf1, NULL, 10); | |
| 93 } else if (!strcmp(buf1, "MAXVAL")) { | |
| 94 pnm_get(s, buf1, sizeof(buf1)); | |
| 95 maxval = strtol(buf1, NULL, 10); | |
| 96 } else if (!strcmp(buf1, "TUPLETYPE")) { | |
| 97 pnm_get(s, tuple_type, sizeof(tuple_type)); | |
| 98 } else if (!strcmp(buf1, "ENDHDR")) { | |
| 99 break; | |
| 100 } else { | |
| 101 return -1; | |
| 102 } | |
| 103 } | |
| 104 /* check that all tags are present */ | |
|
12462
ffb3668ff7af
Use new imgutils.h API names, fix deprecation warnings.
stefano
parents:
12372
diff
changeset
|
105 if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || av_image_check_size(w, h, 0, avctx)) |
| 4978 | 106 return -1; |
| 107 | |
|
10459
a6bb56636f90
whitespace cosmetics: K&R coding style, prettyprinting
diego
parents:
9145
diff
changeset
|
108 avctx->width = w; |
| 4978 | 109 avctx->height = h; |
| 110 if (depth == 1) { | |
| 111 if (maxval == 1) | |
| 112 avctx->pix_fmt = PIX_FMT_MONOWHITE; | |
| 113 else | |
| 114 avctx->pix_fmt = PIX_FMT_GRAY8; | |
| 115 } else if (depth == 3) { | |
|
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
116 if (maxval < 256) { |
| 4978 | 117 avctx->pix_fmt = PIX_FMT_RGB24; |
|
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
118 } else { |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
119 av_log(avctx, AV_LOG_ERROR, "16-bit components are only supported for grayscale\n"); |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
120 avctx->pix_fmt = PIX_FMT_NONE; |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
121 return -1; |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
122 } |
| 4978 | 123 } else if (depth == 4) { |
| 124 avctx->pix_fmt = PIX_FMT_RGB32; | |
| 125 } else { | |
| 126 return -1; | |
| 127 } | |
| 128 return 0; | |
| 129 } else { | |
| 130 return -1; | |
| 131 } | |
| 132 pnm_get(s, buf1, sizeof(buf1)); | |
| 133 avctx->width = atoi(buf1); | |
| 134 if (avctx->width <= 0) | |
| 135 return -1; | |
| 136 pnm_get(s, buf1, sizeof(buf1)); | |
| 137 avctx->height = atoi(buf1); | |
|
12462
ffb3668ff7af
Use new imgutils.h API names, fix deprecation warnings.
stefano
parents:
12372
diff
changeset
|
138 if(av_image_check_size(avctx->width, avctx->height, 0, avctx)) |
| 4978 | 139 return -1; |
| 140 if (avctx->pix_fmt != PIX_FMT_MONOWHITE) { | |
| 141 pnm_get(s, buf1, sizeof(buf1)); | |
| 142 s->maxval = atoi(buf1); | |
|
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
143 if (s->maxval >= 256) { |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
144 if (avctx->pix_fmt == PIX_FMT_GRAY8) { |
| 7865 | 145 avctx->pix_fmt = PIX_FMT_GRAY16BE; |
| 146 if (s->maxval != 65535) | |
| 147 avctx->pix_fmt = PIX_FMT_GRAY16; | |
|
9145
de31b10455cc
pnm: Add missing 'else'. Fixes decoding for 16-bit pgm.
jbr
parents:
9002
diff
changeset
|
148 } else if (avctx->pix_fmt == PIX_FMT_RGB24) { |
| 9002 | 149 if (s->maxval > 255) |
| 150 avctx->pix_fmt = PIX_FMT_RGB48BE; | |
|
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
151 } else { |
| 9002 | 152 av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format\n"); |
|
7859
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
153 avctx->pix_fmt = PIX_FMT_NONE; |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
154 return -1; |
|
48d00b406a26
Return error when trying to decode non-grayscale 16-bit PNM images.
jbr
parents:
6750
diff
changeset
|
155 } |
| 4978 | 156 } |
| 10612 | 157 }else |
| 158 s->maxval=1; | |
| 4978 | 159 /* more check if YUV420 */ |
| 160 if (avctx->pix_fmt == PIX_FMT_YUV420P) { | |
| 161 if ((avctx->width & 1) != 0) | |
| 162 return -1; | |
| 163 h = (avctx->height * 2); | |
| 164 if ((h % 3) != 0) | |
| 165 return -1; | |
| 166 h /= 3; | |
| 167 avctx->height = h; | |
| 168 } | |
| 169 return 0; | |
| 170 } | |
|
10460
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
171 |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
172 av_cold int ff_pnm_end(AVCodecContext *avctx) |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
173 { |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
174 PNMContext *s = avctx->priv_data; |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
175 |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
176 if (s->picture.data[0]) |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
177 avctx->release_buffer(avctx, &s->picture); |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
178 |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
179 return 0; |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
180 } |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
181 |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
182 av_cold int ff_pnm_init(AVCodecContext *avctx) |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
183 { |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
184 PNMContext *s = avctx->priv_data; |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
185 |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
186 avcodec_get_frame_defaults((AVFrame*)&s->picture); |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
187 avctx->coded_frame = (AVFrame*)&s->picture; |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
188 |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
189 return 0; |
|
059265d3cc65
Move PNM init/end functions to the PNM common code.
diego
parents:
10459
diff
changeset
|
190 } |
