History

avcodec: add LSCR decoder

Fixes #4711.

Paul B Mahol committed 7 years ago

Commit 16f7c1f1 parent 3e102239 files · +168 −1Browse files

Unified · Split

9 files
  1. Changelog +1 −0
  2. configure +1 −0
  3. libavcodec/Makefile +1 −0
  4. libavcodec/allcodecs.c +1 −0
  5. libavcodec/avcodec.h +1 −0
  6. libavcodec/codec_desc.c +7 −0
  7. libavcodec/pngdec.c +154 −0
  8. libavcodec/version.h +1 −1
  9. libavformat/riff.c +1 −0
Changelog+1−0
@@ -23,6 +23,7 @@ version <next>: · 22 unmodified lines
23- agm decoder23- agm decoder
24- KUX demuxer24- KUX demuxer
25- AV1 frame split bitstream filter25- AV1 frame split bitstream filter
26- lscr decoder
26 27
27 28
28version 4.1:29version 4.1:
configure+1−0
@@ -2712,6 +2712,7 @@ jpegls_decoder_select="mjpeg_decoder" · 2711 unmodified lines
2712jv_decoder_select="blockdsp"2712jv_decoder_select="blockdsp"
2713lagarith_decoder_select="llviddsp"2713lagarith_decoder_select="llviddsp"
2714ljpeg_encoder_select="idctdsp jpegtables mpegvideoenc"2714ljpeg_encoder_select="idctdsp jpegtables mpegvideoenc"
2715lscr_decoder_deps="zlib"
2715magicyuv_decoder_select="llviddsp"2716magicyuv_decoder_select="llviddsp"
2716magicyuv_encoder_select="llvidencdsp"2717magicyuv_encoder_select="llvidencdsp"
2717mdec_decoder_select="blockdsp idctdsp mpegvideo"2718mdec_decoder_select="blockdsp idctdsp mpegvideo"
libavcodec/Makefile+1−0
@@ -413,6 +413,7 @@ OBJS-$(CONFIG_KMVC_DECODER) += kmvc.o · 412 unmodified lines
413OBJS-$(CONFIG_LAGARITH_DECODER) += lagarith.o lagarithrac.o413OBJS-$(CONFIG_LAGARITH_DECODER) += lagarith.o lagarithrac.o
414OBJS-$(CONFIG_LJPEG_ENCODER) += ljpegenc.o mjpegenc_common.o414OBJS-$(CONFIG_LJPEG_ENCODER) += ljpegenc.o mjpegenc_common.o
415OBJS-$(CONFIG_LOCO_DECODER) += loco.o415OBJS-$(CONFIG_LOCO_DECODER) += loco.o
416OBJS-$(CONFIG_LSCR_DECODER) += png.o pngdec.o pngdsp.o
416OBJS-$(CONFIG_M101_DECODER) += m101.o417OBJS-$(CONFIG_M101_DECODER) += m101.o
417OBJS-$(CONFIG_MACE3_DECODER) += mace.o418OBJS-$(CONFIG_MACE3_DECODER) += mace.o
418OBJS-$(CONFIG_MACE6_DECODER) += mace.o419OBJS-$(CONFIG_MACE6_DECODER) += mace.o
libavcodec/allcodecs.c+1−0
@@ -173,6 +173,7 @@ extern AVCodec ff_kmvc_decoder; · 172 unmodified lines
173extern AVCodec ff_lagarith_decoder;173extern AVCodec ff_lagarith_decoder;
174extern AVCodec ff_ljpeg_encoder;174extern AVCodec ff_ljpeg_encoder;
175extern AVCodec ff_loco_decoder;175extern AVCodec ff_loco_decoder;
176extern AVCodec ff_lscr_decoder;
176extern AVCodec ff_m101_decoder;177extern AVCodec ff_m101_decoder;
177extern AVCodec ff_magicyuv_encoder;178extern AVCodec ff_magicyuv_encoder;
178extern AVCodec ff_magicyuv_decoder;179extern AVCodec ff_magicyuv_decoder;
libavcodec/avcodec.h+1−0
@@ -455,6 +455,7 @@ enum AVCodecID { · 454 unmodified lines
455 AV_CODEC_ID_HYMT,455 AV_CODEC_ID_HYMT,
456 AV_CODEC_ID_ARBC,456 AV_CODEC_ID_ARBC,
457 AV_CODEC_ID_AGM,457 AV_CODEC_ID_AGM,
458 AV_CODEC_ID_LSCR,
458 459
459 /* various PCM "codecs" */460 /* various PCM "codecs" */
460 AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs461 AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
libavcodec/codec_desc.c+7−0
@@ -1712,6 +1712,13 @@ static const AVCodecDescriptor codec_descriptors[] = { · 1711 unmodified lines
1712 .long_name = NULL_IF_CONFIG_SMALL("Amuse Graphics Movie"),1712 .long_name = NULL_IF_CONFIG_SMALL("Amuse Graphics Movie"),
1713 .props = AV_CODEC_PROP_LOSSY,1713 .props = AV_CODEC_PROP_LOSSY,
1714 },1714 },
1715 {
1716 .id = AV_CODEC_ID_LSCR,
1717 .type = AVMEDIA_TYPE_VIDEO,
1718 .name = "lscr",
1719 .long_name = NULL_IF_CONFIG_SMALL("LEAD Screen Capture"),
1720 .props = AV_CODEC_PROP_LOSSY,
1721 },
1715 1722
1716 /* various PCM "codecs" */1723 /* various PCM "codecs" */
1717 {1724 {
libavcodec/pngdec.c+154−0
@@ -1525,6 +1525,141 @@ end: · 1524 unmodified lines
1525}1525}
1526#endif1526#endif
1527 1527
1528#if CONFIG_LSCR_DECODER
1529static int decode_frame_lscr(AVCodecContext *avctx,
1530 void *data, int *got_frame,
1531 AVPacket *avpkt)
1532{
1533 PNGDecContext *const s = avctx->priv_data;
1534 GetByteContext *gb = &s->gb;
1535 AVFrame *frame = data;
1536 int ret, nb_blocks, offset = 0;
1537
1538 bytestream2_init(gb, avpkt->data, avpkt->size);
1539
1540 if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
1541 return ret;
1542
1543 nb_blocks = bytestream2_get_le16(gb);
1544
1545 if (s->last_picture.f->data[0]) {
1546 ret = av_frame_copy(frame, s->last_picture.f);
1547 if (ret < 0)
1548 return ret;
1549 }
1550
1551 for (int b = 0; b < nb_blocks; b++) {
1552 int x, y, x2, y2, w, h, left;
1553 uint32_t csize, size;
1554
1555 s->zstream.zalloc = ff_png_zalloc;
1556 s->zstream.zfree = ff_png_zfree;
1557 s->zstream.opaque = NULL;
1558
1559 if ((ret = inflateInit(&s->zstream)) != Z_OK) {
1560 av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);
1561 ret = AVERROR_EXTERNAL;
1562 goto end;
1563 }
1564
1565 bytestream2_seek(gb, 2 + b * 12, SEEK_SET);
1566
1567 x = bytestream2_get_le16(gb);
1568 y = bytestream2_get_le16(gb);
1569 x2 = bytestream2_get_le16(gb);
1570 y2 = bytestream2_get_le16(gb);
1571 s->width = s->cur_w = w = x2-x;
1572 s->height = s->cur_h = h = y2-y;
1573
1574 if (w <= 0 || x < 0 || x >= avctx->width || w + x > avctx->width ||
1575 h <= 0 || y < 0 || y >= avctx->height || h + y > avctx->height) {
1576 ret = AVERROR_INVALIDDATA;
1577 goto end;
1578 }
1579
1580 size = bytestream2_get_le32(gb);
1581
1582 frame->key_frame = (nb_blocks == 1) &&
1583 (w == avctx->width) &&
1584 (h == avctx->height) &&
1585 (x == 0) && (y == 0);
1586
1587 bytestream2_seek(gb, 2 + nb_blocks * 12 + offset, SEEK_SET);
1588 csize = bytestream2_get_be32(gb);
1589 if (bytestream2_get_le32(gb) != MKTAG('I', 'D', 'A', 'T')) {
1590 ret = AVERROR_INVALIDDATA;
1591 goto end;
1592 }
1593
1594 offset += size;
1595 left = size;
1596
1597 s->y = 0;
1598 s->row_size = w * 3;
1599
1600 av_fast_padded_malloc(&s->buffer, &s->buffer_size, s->row_size + 16);
1601 if (!s->buffer) {
1602 ret = AVERROR(ENOMEM);
1603 goto end;
1604 }
1605
1606 av_fast_padded_malloc(&s->last_row, &s->last_row_size, s->row_size);
1607 if (!s->last_row) {
1608 ret = AVERROR(ENOMEM);
1609 goto end;
1610 }
1611
1612 s->crow_size = w * 3 + 1;
1613 s->crow_buf = s->buffer + 15;
1614 s->zstream.avail_out = s->crow_size;
1615 s->zstream.next_out = s->crow_buf;
1616 s->image_buf = frame->data[0] + (avctx->height - y - 1) * frame->linesize[0] + x * 3;
1617 s->image_linesize =-frame->linesize[0];
1618 s->bpp = 3;
1619 s->pic_state = 0;
1620
1621 while (left > 16) {
1622 ret = png_decode_idat(s, csize);
1623 if (ret < 0)
1624 goto end;
1625 left -= csize + 16;
1626 if (left > 16) {
1627 bytestream2_skip(gb, 4);
1628 csize = bytestream2_get_be32(gb);
1629 if (bytestream2_get_le32(gb) != MKTAG('I', 'D', 'A', 'T')) {
1630 ret = AVERROR_INVALIDDATA;
1631 goto end;
1632 }
1633 }
1634 }
1635
1636 inflateEnd(&s->zstream);
1637 }
1638
1639 frame->pict_type = frame->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
1640
1641 av_frame_unref(s->last_picture.f);
1642 if ((ret = av_frame_ref(s->last_picture.f, frame)) < 0)
1643 return ret;
1644
1645 *got_frame = 1;
1646end:
1647 inflateEnd(&s->zstream);
1648
1649 if (ret < 0)
1650 return ret;
1651 return avpkt->size;
1652}
1653
1654static void decode_flush(AVCodecContext *avctx)
1655{
1656 PNGDecContext *s = avctx->priv_data;
1657
1658 av_frame_unref(s->last_picture.f);
1659}
1660
1661#endif
1662
1528#if HAVE_THREADS1663#if HAVE_THREADS
1529static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)1664static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
1530{1665{
@@ -1581,6 +1716,9 @@ static av_cold int png_dec_init(AVCodecContext *avctx) · 50 unmodified lines
1581 1716
1582 avctx->color_range = AVCOL_RANGE_JPEG;1717 avctx->color_range = AVCOL_RANGE_JPEG;
1583 1718
1719 if (avctx->codec_id == AV_CODEC_ID_LSCR)
1720 avctx->pix_fmt = AV_PIX_FMT_BGR24;
1721
1584 s->avctx = avctx;1722 s->avctx = avctx;
1585 s->previous_picture.f = av_frame_alloc();1723 s->previous_picture.f = av_frame_alloc();
1586 s->last_picture.f = av_frame_alloc();1724 s->last_picture.f = av_frame_alloc();
@@ -1653,3 +1791,19 @@ AVCodec ff_png_decoder = { · 66 unmodified lines
1653 .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_THREADSAFE,1791 .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_THREADSAFE,
1654};1792};
1655#endif1793#endif
1794
1795#if CONFIG_LSCR_DECODER
1796AVCodec ff_lscr_decoder = {
1797 .name = "lscr",
1798 .long_name = NULL_IF_CONFIG_SMALL("LEAD Screen Capture"),
1799 .type = AVMEDIA_TYPE_VIDEO,
1800 .id = AV_CODEC_ID_LSCR,
1801 .priv_data_size = sizeof(PNGDecContext),
1802 .init = png_dec_init,
1803 .close = png_dec_end,
1804 .decode = decode_frame_lscr,
1805 .flush = decode_flush,
1806 .capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/,
1807 .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_THREADSAFE,
1808};
1809#endif
libavcodec/version.h+1−1
@@ -28,7 +28,7 @@ · 27 unmodified lines
28#include "libavutil/version.h"28#include "libavutil/version.h"
29 29
30#define LIBAVCODEC_VERSION_MAJOR 5830#define LIBAVCODEC_VERSION_MAJOR 58
31#define LIBAVCODEC_VERSION_MINOR 5031#define LIBAVCODEC_VERSION_MINOR 51
32#define LIBAVCODEC_VERSION_MICRO 10032#define LIBAVCODEC_VERSION_MICRO 100
33 33
34#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \34#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
libavformat/riff.c+1−0
@@ -485,6 +485,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { · 484 unmodified lines
485 { AV_CODEC_ID_AGM, MKTAG('A', 'G', 'M', '5') },485 { AV_CODEC_ID_AGM, MKTAG('A', 'G', 'M', '5') },
486 { AV_CODEC_ID_AGM, MKTAG('A', 'G', 'M', '6') },486 { AV_CODEC_ID_AGM, MKTAG('A', 'G', 'M', '6') },
487 { AV_CODEC_ID_AGM, MKTAG('A', 'G', 'M', '7') },487 { AV_CODEC_ID_AGM, MKTAG('A', 'G', 'M', '7') },
488 { AV_CODEC_ID_LSCR, MKTAG('L', 'S', 'C', 'R') },
488 { AV_CODEC_ID_NONE, 0 }489 { AV_CODEC_ID_NONE, 0 }
489};490};
490 491

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t