mjpegb support (need more samples)
Originally committed as revision 1258 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
@@ -73,6 +73,7 @@ void avcodec_register_all(void)
|
|||||||
register_avcodec(&dvvideo_decoder);
|
register_avcodec(&dvvideo_decoder);
|
||||||
// register_avcodec(&dvaudio_decoder);
|
// register_avcodec(&dvaudio_decoder);
|
||||||
register_avcodec(&mjpeg_decoder);
|
register_avcodec(&mjpeg_decoder);
|
||||||
|
register_avcodec(&mjpegb_decoder);
|
||||||
register_avcodec(&mp2_decoder);
|
register_avcodec(&mp2_decoder);
|
||||||
register_avcodec(&mp3_decoder);
|
register_avcodec(&mp3_decoder);
|
||||||
register_avcodec(&wmav1_decoder);
|
register_avcodec(&wmav1_decoder);
|
||||||
|
@@ -18,6 +18,7 @@ enum CodecID {
|
|||||||
CODEC_ID_VORBIS,
|
CODEC_ID_VORBIS,
|
||||||
CODEC_ID_AC3,
|
CODEC_ID_AC3,
|
||||||
CODEC_ID_MJPEG,
|
CODEC_ID_MJPEG,
|
||||||
|
CODEC_ID_MJPEGB,
|
||||||
CODEC_ID_MPEG4,
|
CODEC_ID_MPEG4,
|
||||||
CODEC_ID_RAWVIDEO,
|
CODEC_ID_RAWVIDEO,
|
||||||
CODEC_ID_MSMPEG4V1,
|
CODEC_ID_MSMPEG4V1,
|
||||||
@@ -858,6 +859,7 @@ extern AVCodec dvaudio_decoder;
|
|||||||
extern AVCodec wmav1_decoder;
|
extern AVCodec wmav1_decoder;
|
||||||
extern AVCodec wmav2_decoder;
|
extern AVCodec wmav2_decoder;
|
||||||
extern AVCodec mjpeg_decoder;
|
extern AVCodec mjpeg_decoder;
|
||||||
|
extern AVCodec mjpegb_decoder;
|
||||||
extern AVCodec mp2_decoder;
|
extern AVCodec mp2_decoder;
|
||||||
extern AVCodec mp3_decoder;
|
extern AVCodec mp3_decoder;
|
||||||
extern AVCodec mace3_decoder;
|
extern AVCodec mace3_decoder;
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
*
|
||||||
* Support for external huffman table, various fixes (AVID workaround),
|
* Support for external huffman table, various fixes (AVID workaround),
|
||||||
* aspecting and new decode_frame mechanism
|
* aspecting, new decode_frame mechanism and apple mjpeg-b support
|
||||||
* by Alex Beregszaszi <alex@naxine.org>
|
* by Alex Beregszaszi <alex@naxine.org>
|
||||||
*/
|
*/
|
||||||
//#define DEBUG
|
//#define DEBUG
|
||||||
@@ -1061,7 +1061,7 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
|
|||||||
h_count[0] = 1;
|
h_count[0] = 1;
|
||||||
v_count[0] = 1;
|
v_count[0] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(mb_y = 0; mb_y < mb_height; mb_y++) {
|
for(mb_y = 0; mb_y < mb_height; mb_y++) {
|
||||||
for(mb_x = 0; mb_x < mb_width; mb_x++) {
|
for(mb_x = 0; mb_x < mb_width; mb_x++) {
|
||||||
for(i=0;i<nb_components;i++) {
|
for(i=0;i<nb_components;i++) {
|
||||||
@@ -1098,8 +1098,8 @@ static int mjpeg_decode_sos(MJpegDecodeContext *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* (< 1350) buggy workaround for Spectralfan.mov, should be fixed */
|
/* (< 1350) buggy workaround for Spectralfan.mov, should be fixed */
|
||||||
|
if (s->restart_interval && (s->restart_interval < 1350) &&
|
||||||
if ((s->restart_interval < 1350) && !--s->restart_count) {
|
!--s->restart_count) {
|
||||||
align_get_bits(&s->gb);
|
align_get_bits(&s->gb);
|
||||||
skip_bits(&s->gb, 16); /* skip RSTn */
|
skip_bits(&s->gb, 16); /* skip RSTn */
|
||||||
for (j=0; j<nb_components; j++) /* reset dc */
|
for (j=0; j<nb_components; j++) /* reset dc */
|
||||||
@@ -1373,10 +1373,6 @@ static int mjpeg_decode_frame(AVCodecContext *avctx,
|
|||||||
{
|
{
|
||||||
UINT8 x = *(src++);
|
UINT8 x = *(src++);
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (x == 0xff && *src == 0xff)
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
*(dst++) = x;
|
*(dst++) = x;
|
||||||
if (x == 0xff)
|
if (x == 0xff)
|
||||||
{
|
{
|
||||||
@@ -1510,12 +1506,135 @@ not_the_end:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
the_end:
|
the_end:
|
||||||
|
|
||||||
dprintf("mjpeg decode frame unused %d bytes\n", buf_end - buf_ptr);
|
dprintf("mjpeg decode frame unused %d bytes\n", buf_end - buf_ptr);
|
||||||
// return buf_end - buf_ptr;
|
// return buf_end - buf_ptr;
|
||||||
return buf_ptr - buf;
|
return buf_ptr - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mjpegb_decode_frame(AVCodecContext *avctx,
|
||||||
|
void *data, int *data_size,
|
||||||
|
UINT8 *buf, int buf_size)
|
||||||
|
{
|
||||||
|
MJpegDecodeContext *s = avctx->priv_data;
|
||||||
|
UINT8 *buf_end, *buf_ptr;
|
||||||
|
int i;
|
||||||
|
AVPicture *picture = data;
|
||||||
|
GetBitContext hgb; /* for the header */
|
||||||
|
uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs;
|
||||||
|
uint32_t field_size;
|
||||||
|
|
||||||
|
*data_size = 0;
|
||||||
|
|
||||||
|
/* no supplementary picture */
|
||||||
|
if (buf_size == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
buf_ptr = buf;
|
||||||
|
buf_end = buf + buf_size;
|
||||||
|
|
||||||
|
read_header:
|
||||||
|
/* reset on every SOI */
|
||||||
|
s->restart_interval = 0;
|
||||||
|
|
||||||
|
init_get_bits(&hgb, buf_ptr, /*buf_size*/buf_end - buf_ptr);
|
||||||
|
|
||||||
|
skip_bits(&hgb, 32); /* reserved zeros */
|
||||||
|
|
||||||
|
if (get_bits(&hgb, 32) != be2me_32(ff_get_fourcc("mjpg")))
|
||||||
|
{
|
||||||
|
dprintf("not mjpeg-b (bad fourcc)\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
field_size = get_bits(&hgb, 32); /* field size */
|
||||||
|
dprintf("field size: 0x%x\n", field_size);
|
||||||
|
skip_bits(&hgb, 32); /* padded field size */
|
||||||
|
second_field_offs = get_bits(&hgb, 32);
|
||||||
|
dprintf("second field offs: 0x%x\n", second_field_offs);
|
||||||
|
if (second_field_offs)
|
||||||
|
s->interlaced = 1;
|
||||||
|
|
||||||
|
dqt_offs = get_bits(&hgb, 32);
|
||||||
|
dprintf("dqt offs: 0x%x\n", dqt_offs);
|
||||||
|
if (dqt_offs)
|
||||||
|
{
|
||||||
|
init_get_bits(&s->gb, buf+dqt_offs, buf_end - (buf+dqt_offs));
|
||||||
|
s->start_code = DQT;
|
||||||
|
mjpeg_decode_dqt(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
dht_offs = get_bits(&hgb, 32);
|
||||||
|
dprintf("dht offs: 0x%x\n", dht_offs);
|
||||||
|
if (dht_offs)
|
||||||
|
{
|
||||||
|
init_get_bits(&s->gb, buf+dht_offs, buf_end - (buf+dht_offs));
|
||||||
|
s->start_code = DHT;
|
||||||
|
mjpeg_decode_dht(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
sof_offs = get_bits(&hgb, 32);
|
||||||
|
dprintf("sof offs: 0x%x\n", sof_offs);
|
||||||
|
if (sof_offs)
|
||||||
|
{
|
||||||
|
init_get_bits(&s->gb, buf+sof_offs, buf_end - (buf+sof_offs));
|
||||||
|
s->start_code = SOF0;
|
||||||
|
mjpeg_decode_sof0(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
sos_offs = get_bits(&hgb, 32);
|
||||||
|
dprintf("sos offs: 0x%x\n", sos_offs);
|
||||||
|
if (sos_offs)
|
||||||
|
{
|
||||||
|
// init_get_bits(&s->gb, buf+sos_offs, buf_end - (buf+sos_offs));
|
||||||
|
init_get_bits(&s->gb, buf+sos_offs, field_size);
|
||||||
|
s->start_code = SOS;
|
||||||
|
mjpeg_decode_sos(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_bits(&hgb, 32); /* start of data offset */
|
||||||
|
|
||||||
|
if (s->interlaced) {
|
||||||
|
s->bottom_field ^= 1;
|
||||||
|
/* if not bottom field, do not output image yet */
|
||||||
|
if (s->bottom_field && second_field_offs)
|
||||||
|
{
|
||||||
|
buf_ptr = buf + second_field_offs;
|
||||||
|
second_field_offs = 0;
|
||||||
|
goto read_header;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0;i<3;i++) {
|
||||||
|
picture->data[i] = s->current_picture[i];
|
||||||
|
picture->linesize[i] = (s->interlaced) ?
|
||||||
|
s->linesize[i] >> 1 : s->linesize[i];
|
||||||
|
}
|
||||||
|
*data_size = sizeof(AVPicture);
|
||||||
|
avctx->height = s->height;
|
||||||
|
if (s->interlaced)
|
||||||
|
avctx->height *= 2;
|
||||||
|
avctx->width = s->width;
|
||||||
|
/* XXX: not complete test ! */
|
||||||
|
switch((s->h_count[0] << 4) | s->v_count[0]) {
|
||||||
|
case 0x11:
|
||||||
|
avctx->pix_fmt = PIX_FMT_YUV444P;
|
||||||
|
break;
|
||||||
|
case 0x21:
|
||||||
|
avctx->pix_fmt = PIX_FMT_YUV422P;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case 0x22:
|
||||||
|
avctx->pix_fmt = PIX_FMT_YUV420P;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* dummy quality */
|
||||||
|
/* XXX: infer it with matrix */
|
||||||
|
avctx->quality = 3;
|
||||||
|
|
||||||
|
return buf_ptr - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int mjpeg_decode_end(AVCodecContext *avctx)
|
static int mjpeg_decode_end(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
MJpegDecodeContext *s = avctx->priv_data;
|
MJpegDecodeContext *s = avctx->priv_data;
|
||||||
@@ -1543,3 +1662,16 @@ AVCodec mjpeg_decoder = {
|
|||||||
0,
|
0,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AVCodec mjpegb_decoder = {
|
||||||
|
"mjpegb",
|
||||||
|
CODEC_TYPE_VIDEO,
|
||||||
|
CODEC_ID_MJPEGB,
|
||||||
|
sizeof(MJpegDecodeContext),
|
||||||
|
mjpeg_decode_init,
|
||||||
|
NULL,
|
||||||
|
mjpeg_decode_end,
|
||||||
|
mjpegb_decode_frame,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
Reference in New Issue
Block a user