History

avplay: switch to new refcounted frames API

Remove now unused cmdutils get_buffer() implementation.

Anton Khirnov committed 13 years ago

Commit 354468f1 parent 9b2dc293 files · +19 −226Browse files

Unified · Split

3 files
  1. avplay.c +19 −57
  2. cmdutils.c +0 −126
  3. cmdutils.h +0 −43
avplay.c+19−57
@@ -108,9 +108,7 @@ typedef struct VideoPicture { · 107 unmodified lines
108 int reallocate;108 int reallocate;
109 enum AVPixelFormat pix_fmt;109 enum AVPixelFormat pix_fmt;
110 110
111#if CONFIG_AVFILTER111 AVRational sar;
112 AVFilterBufferRef *picref;
113#endif
114} VideoPicture;112} VideoPicture;
115 113
116typedef struct SubPicture {114typedef struct SubPicture {
@@ -217,8 +215,6 @@ typedef struct VideoState { · 100 unmodified lines
217#if CONFIG_AVFILTER215#if CONFIG_AVFILTER
218 AVFilterContext *in_video_filter; // the first filter in the video chain216 AVFilterContext *in_video_filter; // the first filter in the video chain
219 AVFilterContext *out_video_filter; // the last filter in the video chain217 AVFilterContext *out_video_filter; // the last filter in the video chain
220 int use_dr1;
221 FrameBuffer *buffer_pool;
222#endif218#endif
223 219
224 float skip_frames;220 float skip_frames;
@@ -656,10 +652,10 @@ static void video_image_display(VideoState *is) · 431 unmodified lines
656 vp = &is->pictq[is->pictq_rindex];652 vp = &is->pictq[is->pictq_rindex];
657 if (vp->bmp) {653 if (vp->bmp) {
658#if CONFIG_AVFILTER654#if CONFIG_AVFILTER
659 if (vp->picref->video->pixel_aspect.num == 0)655 if (!vp->sar.num)
660 aspect_ratio = 0;656 aspect_ratio = 0;
661 else657 else
662 aspect_ratio = av_q2d(vp->picref->video->pixel_aspect);658 aspect_ratio = av_q2d(vp->sar);
663#else659#else
664 660
665 /* XXX: use variable in the frame */661 /* XXX: use variable in the frame */
@@ -1229,9 +1225,6 @@ static void stream_close(VideoState *is) · 563 unmodified lines
1229 /* free all pictures */1225 /* free all pictures */
1230 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {1226 for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
1231 vp = &is->pictq[i];1227 vp = &is->pictq[i];
1232#if CONFIG_AVFILTER
1233 avfilter_unref_bufferp(&vp->picref);
1234#endif
1235 if (vp->bmp) {1228 if (vp->bmp) {
1236 SDL_FreeYUVOverlay(vp->bmp);1229 SDL_FreeYUVOverlay(vp->bmp);
1237 vp->bmp = NULL;1230 vp->bmp = NULL;
@@ -1279,8 +1272,6 @@ static void alloc_picture(void *opaque) · 41 unmodified lines
1279 SDL_FreeYUVOverlay(vp->bmp);1272 SDL_FreeYUVOverlay(vp->bmp);
1280 1273
1281#if CONFIG_AVFILTER1274#if CONFIG_AVFILTER
1282 avfilter_unref_bufferp(&vp->picref);
1283
1284 vp->width = is->out_video_filter->inputs[0]->w;1275 vp->width = is->out_video_filter->inputs[0]->w;
1285 vp->height = is->out_video_filter->inputs[0]->h;1276 vp->height = is->out_video_filter->inputs[0]->h;
1286 vp->pix_fmt = is->out_video_filter->inputs[0]->format;1277 vp->pix_fmt = is->out_video_filter->inputs[0]->format;
@@ -1369,10 +1360,6 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t · 82 unmodified lines
1369 /* if the frame is not skipped, then display it */1360 /* if the frame is not skipped, then display it */
1370 if (vp->bmp) {1361 if (vp->bmp) {
1371 AVPicture pict = { { 0 } };1362 AVPicture pict = { { 0 } };
1372#if CONFIG_AVFILTER
1373 avfilter_unref_bufferp(&vp->picref);
1374 vp->picref = src_frame->opaque;
1375#endif
1376 1363
1377 /* get a pointer on the bitmap */1364 /* get a pointer on the bitmap */
1378 SDL_LockYUVOverlay (vp->bmp);1365 SDL_LockYUVOverlay (vp->bmp);
@@ -1432,6 +1419,7 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t · 53 unmodified lines
1432static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)1419static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
1433{1420{
1434 double frame_delay, pts;1421 double frame_delay, pts;
1422 int ret;
1435 1423
1436 pts = pts1;1424 pts = pts1;
1437 1425
@@ -1448,7 +1436,9 @@ static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int6 · 10 unmodified lines
1448 frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);1436 frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
1449 is->video_clock += frame_delay;1437 is->video_clock += frame_delay;
1450 1438
1451 return queue_picture(is, src_frame, pts, pos);1439 ret = queue_picture(is, src_frame, pts, pos);
1440 av_frame_unref(src_frame);
1441 return ret;
1452}1442}
1453 1443
1454static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)1444static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
@@ -1504,7 +1494,7 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke · 49 unmodified lines
1504 is->skip_frames_index -= FFMAX(is->skip_frames, 1.0);1494 is->skip_frames_index -= FFMAX(is->skip_frames, 1.0);
1505 return 1;1495 return 1;
1506 }1496 }
1507 1497 av_frame_unref(frame);
1508 }1498 }
1509 return 0;1499 return 0;
1510}1500}
@@ -1572,13 +1562,6 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c · 61 unmodified lines
1572 is->in_video_filter = filt_src;1562 is->in_video_filter = filt_src;
1573 is->out_video_filter = filt_out;1563 is->out_video_filter = filt_out;
1574 1564
1575 if (codec->codec->capabilities & CODEC_CAP_DR1) {
1576 is->use_dr1 = 1;
1577 codec->get_buffer = codec_get_buffer;
1578 codec->release_buffer = codec_release_buffer;
1579 codec->opaque = &is->buffer_pool;
1580 }
1581
1582 return ret;1565 return ret;
1583}1566}
1584 1567
@@ -1588,7 +1571,7 @@ static int video_thread(void *arg) · 3 unmodified lines
1588{1571{
1589 AVPacket pkt = { 0 };1572 AVPacket pkt = { 0 };
1590 VideoState *is = arg;1573 VideoState *is = arg;
1591 AVFrame *frame = avcodec_alloc_frame();1574 AVFrame *frame = av_frame_alloc();
1592 int64_t pts_int;1575 int64_t pts_int;
1593 double pts;1576 double pts;
1594 int ret;1577 int ret;
@@ -1596,7 +1579,6 @@ static int video_thread(void *arg) · 1 unmodified line
1596#if CONFIG_AVFILTER1579#if CONFIG_AVFILTER
1597 AVFilterGraph *graph = avfilter_graph_alloc();1580 AVFilterGraph *graph = avfilter_graph_alloc();
1598 AVFilterContext *filt_out = NULL, *filt_in = NULL;1581 AVFilterContext *filt_out = NULL, *filt_in = NULL;
1599 int64_t pos;
1600 int last_w = is->video_st->codec->width;1582 int last_w = is->video_st->codec->width;
1601 int last_h = is->video_st->codec->height;1583 int last_h = is->video_st->codec->height;
1602 1584
@@ -1608,7 +1590,6 @@ static int video_thread(void *arg) · 5 unmodified lines
1608 1590
1609 for (;;) {1591 for (;;) {
1610#if CONFIG_AVFILTER1592#if CONFIG_AVFILTER
1611 AVFilterBufferRef *picref;
1612 AVRational tb;1593 AVRational tb;
1613#endif1594#endif
1614 while (is->paused && !is->videoq.abort_request)1595 while (is->paused && !is->videoq.abort_request)
@@ -1639,38 +1620,19 @@ static int video_thread(void *arg) · 24 unmodified lines
1639 }1620 }
1640 1621
1641 frame->pts = pts_int;1622 frame->pts = pts_int;
1642 if (is->use_dr1) {1623 ret = av_buffersrc_add_frame(filt_in, frame);
1643 FrameBuffer *buf = frame->opaque;1624 if (ret < 0)
1644 AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays(1625 goto the_end;
1645 frame->data, frame->linesize,
1646 AV_PERM_READ | AV_PERM_PRESERVE,
1647 frame->width, frame->height,
1648 frame->format);
1649
1650 avfilter_copy_frame_props(fb, frame);
1651 fb->buf->priv = buf;
1652 fb->buf->free = filter_release_buffer;
1653
1654 buf->refcount++;
1655 av_buffersrc_buffer(filt_in, fb);
1656
1657 } else
1658 av_buffersrc_write_frame(filt_in, frame);
1659 1626
1660 while (ret >= 0) {1627 while (ret >= 0) {
1661 ret = av_buffersink_read(filt_out, &picref);1628 ret = av_buffersink_get_frame(filt_out, frame);
1662 if (ret < 0) {1629 if (ret < 0) {
1663 ret = 0;1630 ret = 0;
1664 break;1631 break;
1665 }1632 }
1666 1633
1667 avfilter_copy_buf_props(frame, picref);1634 pts_int = frame->pts;
1668
1669 pts_int = picref->pts;
1670 tb = filt_out->inputs[0]->time_base;1635 tb = filt_out->inputs[0]->time_base;
1671 pos = picref->pos;
1672 frame->opaque = picref;
1673
1674 if (av_cmp_q(tb, is->video_st->time_base)) {1636 if (av_cmp_q(tb, is->video_st->time_base)) {
1675 av_unused int64_t pts1 = pts_int;1637 av_unused int64_t pts1 = pts_int;
1676 pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);1638 pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
@@ -1680,7 +1642,7 @@ static int video_thread(void *arg) · 3 unmodified lines
1680 is->video_st->time_base.num, is->video_st->time_base.den, pts_int);1642 is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
1681 }1643 }
1682 pts = pts_int * av_q2d(is->video_st->time_base);1644 pts = pts_int * av_q2d(is->video_st->time_base);
1683 ret = output_picture2(is, frame, pts, pos);1645 ret = output_picture2(is, frame, pts, 0);
1684 }1646 }
1685#else1647#else
1686 pts = pts_int * av_q2d(is->video_st->time_base);1648 pts = pts_int * av_q2d(is->video_st->time_base);
@@ -1690,6 +1652,7 @@ static int video_thread(void *arg) · 3 unmodified lines
1690 if (ret < 0)1652 if (ret < 0)
1691 goto the_end;1653 goto the_end;
1692 1654
1655
1693 if (step)1656 if (step)
1694 if (cur_stream)1657 if (cur_stream)
1695 stream_pause(cur_stream);1658 stream_pause(cur_stream);
@@ -1700,7 +1663,7 @@ static int video_thread(void *arg) · 4 unmodified lines
1700 avfilter_graph_free(&graph);1663 avfilter_graph_free(&graph);
1701#endif1664#endif
1702 av_free_packet(&pkt);1665 av_free_packet(&pkt);
1703 avcodec_free_frame(&frame);1666 av_frame_free(&frame);
1704 return 0;1667 return 0;
1705}1668}
1706 1669
@@ -2090,6 +2053,8 @@ static int stream_component_open(VideoState *is, int stream_index) · 383 unmodified lines
2090 2053
2091 if (!av_dict_get(opts, "threads", NULL, 0))2054 if (!av_dict_get(opts, "threads", NULL, 0))
2092 av_dict_set(&opts, "threads", "auto", 0);2055 av_dict_set(&opts, "threads", "auto", 0);
2056 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO)
2057 av_dict_set(&opts, "refcounted_frames", "1", 0);
2093 if (!codec ||2058 if (!codec ||
2094 avcodec_open2(avctx, codec, &opts) < 0)2059 avcodec_open2(avctx, codec, &opts) < 0)
2095 return -1;2060 return -1;
@@ -2235,9 +2200,6 @@ static void stream_component_close(VideoState *is, int stream_index) · 139 unmodified lines
2235 2200
2236 ic->streams[stream_index]->discard = AVDISCARD_ALL;2201 ic->streams[stream_index]->discard = AVDISCARD_ALL;
2237 avcodec_close(avctx);2202 avcodec_close(avctx);
2238#if CONFIG_AVFILTER
2239 free_buffer_pool(&is->buffer_pool);
2240#endif
2241 switch (avctx->codec_type) {2203 switch (avctx->codec_type) {
2242 case AVMEDIA_TYPE_AUDIO:2204 case AVMEDIA_TYPE_AUDIO:
2243 is->audio_st = NULL;2205 is->audio_st = NULL;
cmdutils.c+0−126
@@ -1543,129 +1543,3 @@ void *grow_array(void *array, int elem_size, int *size, int new_size) · 1542 unmodified lines
1543 }1543 }
1544 return array;1544 return array;
1545}1545}
1546
1547static int alloc_buffer(FrameBuffer **pool, AVCodecContext *s, FrameBuffer **pbuf)
1548{
1549 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->pix_fmt);
1550 FrameBuffer *buf;
1551 int i, ret;
1552 int pixel_size;
1553 int h_chroma_shift, v_chroma_shift;
1554 int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails on svq1
1555 int w = s->width, h = s->height;
1556
1557 if (!desc)
1558 return AVERROR(EINVAL);
1559 pixel_size = desc->comp[0].step_minus1 + 1;
1560
1561 buf = av_mallocz(sizeof(*buf));
1562 if (!buf)
1563 return AVERROR(ENOMEM);
1564
1565 if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {
1566 w += 2*edge;
1567 h += 2*edge;
1568 }
1569
1570 avcodec_align_dimensions(s, &w, &h);
1571 if ((ret = av_image_alloc(buf->base, buf->linesize, w, h,
1572 s->pix_fmt, 32)) < 0) {
1573 av_freep(&buf);
1574 return ret;
1575 }
1576
1577 av_pix_fmt_get_chroma_sub_sample(s->pix_fmt,
1578 &h_chroma_shift, &v_chroma_shift);
1579
1580 for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
1581 const int h_shift = i==0 ? 0 : h_chroma_shift;
1582 const int v_shift = i==0 ? 0 : v_chroma_shift;
1583 if (s->flags & CODEC_FLAG_EMU_EDGE)
1584 buf->data[i] = buf->base[i];
1585 else if (buf->base[i])
1586 buf->data[i] = buf->base[i] +
1587 FFALIGN((buf->linesize[i]*edge >> v_shift) +
1588 (pixel_size*edge >> h_shift), 32);
1589 }
1590 buf->w = s->width;
1591 buf->h = s->height;
1592 buf->pix_fmt = s->pix_fmt;
1593 buf->pool = pool;
1594
1595 *pbuf = buf;
1596 return 0;
1597}
1598
1599int codec_get_buffer(AVCodecContext *s, AVFrame *frame)
1600{
1601 FrameBuffer **pool = s->opaque;
1602 FrameBuffer *buf;
1603 int ret, i;
1604
1605 if (!*pool && (ret = alloc_buffer(pool, s, pool)) < 0)
1606 return ret;
1607
1608 buf = *pool;
1609 *pool = buf->next;
1610 buf->next = NULL;
1611 if (buf->w != s->width || buf->h != s->height || buf->pix_fmt != s->pix_fmt) {
1612 av_freep(&buf->base[0]);
1613 av_free(buf);
1614 if ((ret = alloc_buffer(pool, s, &buf)) < 0)
1615 return ret;
1616 }
1617 buf->refcount++;
1618
1619 frame->opaque = buf;
1620 frame->type = FF_BUFFER_TYPE_USER;
1621 frame->extended_data = frame->data;
1622
1623 for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
1624 frame->base[i] = buf->base[i]; // XXX h264.c uses base though it shouldn't
1625 frame->data[i] = buf->data[i];
1626 frame->linesize[i] = buf->linesize[i];
1627 }
1628
1629 return 0;
1630}
1631
1632static void unref_buffer(FrameBuffer *buf)
1633{
1634 FrameBuffer **pool = buf->pool;
1635
1636 av_assert0(buf->refcount);
1637 buf->refcount--;
1638 if (!buf->refcount) {
1639 buf->next = *pool;
1640 *pool = buf;
1641 }
1642}
1643
1644void codec_release_buffer(AVCodecContext *s, AVFrame *frame)
1645{
1646 FrameBuffer *buf = frame->opaque;
1647 int i;
1648
1649 for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++)
1650 frame->data[i] = NULL;
1651
1652 unref_buffer(buf);
1653}
1654
1655void filter_release_buffer(AVFilterBuffer *fb)
1656{
1657 FrameBuffer *buf = fb->priv;
1658 av_free(fb);
1659 unref_buffer(buf);
1660}
1661
1662void free_buffer_pool(FrameBuffer **pool)
1663{
1664 FrameBuffer *buf = *pool;
1665 while (buf) {
1666 *pool = buf->next;
1667 av_freep(&buf->base[0]);
1668 av_free(buf);
1669 buf = *pool;
1670 }
1671}
cmdutils.h+0−43
@@ -510,49 +510,6 @@ void *grow_array(void *array, int elem_size, int *size, int new_size); · 509 unmodified lines
510#define GROW_ARRAY(array, nb_elems)\510#define GROW_ARRAY(array, nb_elems)\
511 array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1)511 array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1)
512 512
513typedef struct FrameBuffer {
514 uint8_t *base[4];
515 uint8_t *data[4];
516 int linesize[4];
517
518 int h, w;
519 enum AVPixelFormat pix_fmt;
520
521 int refcount;
522 struct FrameBuffer **pool; ///< head of the buffer pool
523 struct FrameBuffer *next;
524} FrameBuffer;
525
526/**
527 * Get a frame from the pool. This is intended to be used as a callback for
528 * AVCodecContext.get_buffer.
529 *
530 * @param s codec context. s->opaque must be a pointer to the head of the
531 * buffer pool.
532 * @param frame frame->opaque will be set to point to the FrameBuffer
533 * containing the frame data.
534 */
535int codec_get_buffer(AVCodecContext *s, AVFrame *frame);
536
537/**
538 * A callback to be used for AVCodecContext.release_buffer along with
539 * codec_get_buffer().
540 */
541void codec_release_buffer(AVCodecContext *s, AVFrame *frame);
542
543/**
544 * A callback to be used for AVFilterBuffer.free.
545 * @param fb buffer to free. fb->priv must be a pointer to the FrameBuffer
546 * containing the buffer data.
547 */
548void filter_release_buffer(AVFilterBuffer *fb);
549
550/**
551 * Free all the buffers in the pool. This must be called after all the
552 * buffers have been released.
553 */
554void free_buffer_pool(FrameBuffer **pool);
555
556#define GET_PIX_FMT_NAME(pix_fmt)\513#define GET_PIX_FMT_NAME(pix_fmt)\
557 const char *name = av_get_pix_fmt_name(pix_fmt);514 const char *name = av_get_pix_fmt_name(pix_fmt);
558 515

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