Mercurial > mplayer.hg
annotate gui/bitmap.c @ 31246:cc6ee3017097
Limit buffered PTS only when we actually got a frame from the decoder.
This avoids some issues with H.264 PAFF due to dropping PTS values too
early because only every second packet actually produced output.
Just keeping up to one additional pts value would have avoided this
particular issue as well, but this is more generic.
author | reimar |
---|---|
date | Thu, 03 Jun 2010 20:59:40 +0000 |
parents | 45dcf93d41fa |
children | 6be4d46328dd |
rev | line source |
---|---|
26458 | 1 /* |
2 * This file is part of MPlayer. | |
3 * | |
4 * MPlayer is free software; you can redistribute it and/or modify | |
5 * it under the terms of the GNU General Public License as published by | |
6 * the Free Software Foundation; either version 2 of the License, or | |
7 * (at your option) any later version. | |
8 * | |
9 * MPlayer is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License along | |
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
17 */ | |
18 | |
23077 | 19 #include <stdio.h> |
20 #include <stdlib.h> | |
21 #include <string.h> | |
22 | |
23 #include "mp_msg.h" | |
24 #include "help_mp.h" | |
25 #include "bitmap.h" | |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
26 #include "libavcodec/avcodec.h" |
23225
794aba782ebd
Fix Gui colors for 32 bit png images after switch to libavcodec decoding
reimar
parents:
23200
diff
changeset
|
27 #include "libavutil/intreadwrite.h" |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
28 #include "libvo/fastmemcpy.h" |
23077 | 29 |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
30 static int pngRead( unsigned char * fname,txSample * bf ) |
23077 | 31 { |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
32 int decode_ok; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
33 void *data; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
34 int len; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
35 AVCodecContext *avctx; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
36 AVFrame *frame; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26458
diff
changeset
|
37 |
23077 | 38 FILE *fp=fopen( fname,"rb" ); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26458
diff
changeset
|
39 if ( !fp ) |
23077 | 40 { |
41 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] file read error ( %s )\n",fname ); | |
42 return 1; | |
43 } | |
44 | |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
45 fseek(fp, 0, SEEK_END); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
46 len = ftell(fp); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
47 if (len > 50 * 1024 * 1024) return 2; |
30388
45dcf93d41fa
Use av_malloc to ensure sufficient alignment and also free at least some
reimar
parents:
30310
diff
changeset
|
48 data = av_malloc(len + FF_INPUT_BUFFER_PADDING_SIZE); |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
49 fseek(fp, 0, SEEK_SET); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
50 fread(data, len, 1, fp); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
51 fclose(fp); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
52 avctx = avcodec_alloc_context(); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
53 frame = avcodec_alloc_frame(); |
23526 | 54 avcodec_register_all(); |
55 avcodec_open(avctx, avcodec_find_decoder(CODEC_ID_PNG)); | |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
56 avcodec_decode_video(avctx, frame, &decode_ok, data, len); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
57 memset(bf, 0, sizeof(*bf)); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
58 switch (avctx->pix_fmt) { |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
59 case PIX_FMT_GRAY8: bf->BPP = 8; break; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
60 case PIX_FMT_GRAY16BE: bf->BPP = 16; break; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
61 case PIX_FMT_RGB24: bf->BPP = 24; break; |
30310
6693b4a6a284
Do not depend on PIX_FMT_RGB32 which is (currently?) not part of the public API.
reimar
parents:
29401
diff
changeset
|
62 case PIX_FMT_BGRA: |
6693b4a6a284
Do not depend on PIX_FMT_RGB32 which is (currently?) not part of the public API.
reimar
parents:
29401
diff
changeset
|
63 case PIX_FMT_ARGB: bf->BPP = 32; break; |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
64 default: bf->BPP = 0; break; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
65 } |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
66 if (decode_ok && bf->BPP) { |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
67 int bpl; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
68 bf->Width = avctx->width; bf->Height = avctx->height; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
69 bpl = bf->Width * (bf->BPP / 8); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
70 bf->ImageSize = bpl * bf->Height; |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
71 bf->Image = malloc(bf->ImageSize); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
72 memcpy_pic(bf->Image, frame->data[0], bpl, bf->Height, bpl, frame->linesize[0]); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
73 } |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
74 avcodec_close(avctx); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
75 av_freep(&frame); |
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
76 av_freep(&avctx); |
30388
45dcf93d41fa
Use av_malloc to ensure sufficient alignment and also free at least some
reimar
parents:
30310
diff
changeset
|
77 av_freep(&data); |
23077 | 78 |
79 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] filename: %s.\n",fname ); | |
80 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] size: %dx%d bits: %d\n",bf->Width,bf->Height,bf->BPP ); | |
81 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[png] imagesize: %lu\n",bf->ImageSize ); | |
23193
7857af1ca50b
Remove libpng dependency for Gui, use libavcodec instead
reimar
parents:
23077
diff
changeset
|
82 return !(decode_ok && bf->BPP); |
23077 | 83 } |
84 | |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
85 static int conv24to32( txSample * bf ) |
23077 | 86 { |
87 unsigned char * tmpImage; | |
88 int i,c; | |
89 | |
90 if ( bf->BPP == 24 ) | |
91 { | |
92 tmpImage=bf->Image; | |
93 bf->ImageSize=bf->Width * bf->Height * 4; | |
94 bf->BPP=32; | |
23200 | 95 if ( ( bf->Image=calloc( 1, bf->ImageSize ) ) == NULL ) |
23077 | 96 { |
23199 | 97 free( tmpImage ); |
23077 | 98 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] not enough memory for image\n" ); |
99 return 1; | |
100 } | |
23225
794aba782ebd
Fix Gui colors for 32 bit png images after switch to libavcodec decoding
reimar
parents:
23200
diff
changeset
|
101 for ( c=0,i=0; c < bf->ImageSize; c += 4, i += 3) |
23077 | 102 { |
23225
794aba782ebd
Fix Gui colors for 32 bit png images after switch to libavcodec decoding
reimar
parents:
23200
diff
changeset
|
103 *(uint32_t *)&bf->Image[c] = AV_RB24(&tmpImage[i]); |
23077 | 104 } |
105 free( tmpImage ); | |
106 } | |
107 return 0; | |
108 } | |
109 | |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
110 static void Normalize( txSample * bf ) |
23077 | 111 { |
112 int i; | |
29401
f01023c524c3
Replace WORDS_BIGENDIAN by HAVE_BIGENDIAN in all internal code.
diego
parents:
29263
diff
changeset
|
113 #if !HAVE_BIGENDIAN |
23077 | 114 for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i+3]=0; |
115 #else | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26458
diff
changeset
|
116 for ( i=0;i < (int)bf->ImageSize;i+=4 ) bf->Image[i]=0; |
23077 | 117 #endif |
118 } | |
119 | |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
120 static unsigned char tmp[512]; |
23077 | 121 |
23196
019bfce0c0dc
Make functions and variables not used outside bitmap.c static
reimar
parents:
23195
diff
changeset
|
122 static unsigned char * fExist( unsigned char * fname ) |
23077 | 123 { |
124 FILE * fl; | |
125 unsigned char ext[][6] = { ".png\0",".PNG\0" }; | |
126 int i; | |
127 | |
128 fl=fopen( fname,"rb" ); | |
129 if ( fl != NULL ) | |
130 { | |
131 fclose( fl ); | |
132 return fname; | |
133 } | |
134 for ( i=0;i<2;i++ ) | |
135 { | |
136 snprintf( tmp,511,"%s%s",fname,ext[i] ); | |
137 fl=fopen( tmp,"rb" ); | |
138 if ( fl != NULL ) | |
139 { | |
140 fclose( fl ); | |
141 return tmp; | |
142 } | |
143 } | |
144 return NULL; | |
145 } | |
146 | |
147 int bpRead( char * fname, txSample * bf ) | |
148 { | |
149 fname=fExist( fname ); | |
150 if ( fname == NULL ) return -2; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26458
diff
changeset
|
151 if ( pngRead( fname,bf ) ) |
23077 | 152 { |
153 mp_dbg( MSGT_GPLAYER,MSGL_FATAL,"[bitmap] unknown file type ( %s )\n",fname ); | |
154 return -5; | |
155 } | |
156 if ( bf->BPP < 24 ) | |
157 { | |
158 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[bitmap] Sorry, only 24 and 32 bpp bitmaps are supported.\n" ); | |
159 return -1; | |
160 } | |
161 if ( conv24to32( bf ) ) return -8; | |
162 Normalize( bf ); | |
163 return 0; | |
164 } | |
165 | |
166 void Convert32to1( txSample * in,txSample * out,int adaptivlimit ) | |
167 { | |
168 out->Width=in->Width; | |
169 out->Height=in->Height; | |
170 out->BPP=1; | |
171 out->ImageSize=(out->Width * out->Height + 7) / 8; | |
172 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[c32to1] imagesize: %d\n",out->ImageSize ); | |
173 out->Image=calloc( 1,out->ImageSize ); | |
174 if ( out->Image == NULL ) mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_NotEnoughMemoryC32To1 ); | |
175 { | |
176 int i,b,c=0; unsigned int * buf = NULL; unsigned char tmp = 0; int nothaveshape = 1; | |
177 buf=(unsigned int *)in->Image; | |
178 for ( b=0,i=0;i < (int)(out->Width * out->Height);i++ ) | |
179 { | |
180 if ( (int)buf[i] != adaptivlimit ) tmp=( tmp >> 1 )|128; | |
181 else { tmp=tmp >> 1; buf[i]=nothaveshape=0; } | |
182 if ( b++ == 7 ) { out->Image[c++]=tmp; tmp=b=0; } | |
183 } | |
184 if ( b ) out->Image[c]=tmp; | |
185 if ( nothaveshape ) { free( out->Image ); out->Image=NULL; } | |
186 } | |
187 } |