comparison libmpdemux/muxer_mpeg.c @ 21482:1dd284e31549

reimplemented :telecine and :film2pal in terms of dgpulldown
author nicodvb
date Mon, 04 Dec 2006 21:20:01 +0000
parents 95c9f47c1cd8
children e065bb0c5485
comparison
equal deleted inserted replaced
21481:95c9f47c1cd8 21482:1dd284e31549
1577 fps = 0; 1577 fps = 0;
1578 period = (vpriv->telecine == TELECINE_FILM2PAL) ? 12 : 4; 1578 period = (vpriv->telecine == TELECINE_FILM2PAL) ? 12 : 4;
1579 if(fps_ptr != NULL) 1579 if(fps_ptr != NULL)
1580 { 1580 {
1581 fps = *fps_ptr & 0x0f; 1581 fps = *fps_ptr & 0x0f;
1582 if(((!fps) || (fps > FRAMERATE_24)) && vpriv->telecine != TELECINE_DGPULLDOWN)
1583 {
1584 mp_msg(MSGT_MUXER, MSGL_ERR, "\nERROR! FRAMERATE IS INVALID: %d, disabling telecining\n", (int) fps);
1585 vpriv->telecine = 0;
1586 return 0;
1587 }
1588 if(vpriv->telecine == TELECINE_FILM2PAL)
1589 {
1590 *fps_ptr = (*fps_ptr & 0xf0) | FRAMERATE_25;
1591 vpriv->nom_delta_pts = parse_fps(25.0);
1592 }
1593 else if(vpriv->telecine == TELECINE_DGPULLDOWN)
1594 {
1595 *fps_ptr = (*fps_ptr & 0xf0) | priv->vframerate; 1582 *fps_ptr = (*fps_ptr & 0xf0) | priv->vframerate;
1596 vpriv->nom_delta_pts = parse_fps(conf_vframerate); 1583 vpriv->nom_delta_pts = parse_fps(conf_vframerate);
1597 }
1598 else
1599 {
1600 *fps_ptr = (*fps_ptr & 0xf0) | (fps + 3);
1601 vpriv->nom_delta_pts = parse_fps((fps + 3) == FRAMERATE_2997 ? 30000.0/1001.0 : 30.0);
1602 }
1603 } 1584 }
1604 1585
1605 //in pce_ptr starting from bit 0 bit 24 is tff, bit 30 is rff, 1586 //in pce_ptr starting from bit 0 bit 24 is tff, bit 30 is rff,
1606 if(pce_ptr[3] & 0x2) 1587 if(pce_ptr[3] & 0x2)
1607 { 1588 {
1620 vpriv->trf = (pce_ptr[3] >> 6) & 0x2; 1601 vpriv->trf = (pce_ptr[3] >> 6) & 0x2;
1621 1602
1622 while(n < 0) n+=period; 1603 while(n < 0) n+=period;
1623 vpriv->trf = (vpriv->trf + n) % period; 1604 vpriv->trf = (vpriv->trf + n) % period;
1624 1605
1625 //sets curent tff/rff bits
1626 if(vpriv->telecine == TELECINE_FILM2PAL)
1627 {
1628 //repeat 1 field every 12 frames
1629 int rest1 = (vpriv->trf % period) == 11;
1630 int rest2 = vpriv->vframes % 999;
1631
1632 rff = 0;
1633 if(rest1)
1634 rff = 2;
1635
1636 if(vpriv->real_framerate == FRAMERATE_23976)
1637 {
1638 //we have to inverse the 1/1000 framedrop, repeating two fields in a sequence of 999 frames
1639 //486 and 978 are ideal because they are halfway in the sequence
1640 //additionally x % 12 == 6 (halfway between two frames with rff set)
1641 //and enough in advance to check if rest1 is valid too,
1642 //so we can delay the setting of rff to current_frame+3 with no risk to leave the
1643 //current sequence unpatched
1644 if(rest2 == 486 || rest2 == 978)
1645 {
1646 if(rest1)
1647 {
1648 //delay the setting by 6 frames, so we don't have 2 consecutive rff
1649 //and the transition will be smoother (halfway in the 12-frames sequence)
1650 vpriv->delay_rff = 7;
1651 mp_msg(MSGT_MUXER, MSGL_V, "\r\nDELAYED: %d\r\n", rest2);
1652 }
1653 else
1654 rff = 2;
1655 }
1656
1657 if(!rest1 && vpriv->delay_rff)
1658 {
1659 vpriv->delay_rff--;
1660 if(vpriv->delay_rff == 1)
1661 {
1662 rff = 2;
1663 vpriv->delay_rff = 0;
1664 mp_msg(MSGT_MUXER, MSGL_V, "\r\nRECOVERED: %d\r\n", rest2);
1665 }
1666 }
1667 }
1668
1669 pce_ptr[3] = (pce_ptr[3] & 0xfd) | rff;
1670 }
1671 else if(vpriv->telecine == TELECINE_DGPULLDOWN)
1672 {
1673 pce_ptr[3] = (pce_ptr[3] & 0xfd) | bff_mask[vpriv->display_frame % MAX_PATTERN_LENGTH]; 1606 pce_ptr[3] = (pce_ptr[3] & 0xfd) | bff_mask[vpriv->display_frame % MAX_PATTERN_LENGTH];
1674 }
1675 else
1676 {
1677 tff = (vpriv->trf & 0x2) ? 0x80 : 0;
1678 rff = (vpriv->trf & 0x1) ? 0x2 : 0;
1679 pce_ptr[3] = (pce_ptr[3] & 0x7d) | tff | rff;
1680 }
1681 pce_ptr[4] |= 0x80; //sets progressive frame 1607 pce_ptr[4] |= 0x80; //sets progressive frame
1682 mp_msg(MSGT_MUXER, MSGL_DBG2, "\nTRF: %d, TFF: %d, RFF: %d, n: %d\n", vpriv->trf, tff >> 7, rff >> 1, n); 1608 mp_msg(MSGT_MUXER, MSGL_DBG2, "\nTRF: %d, TFF: %d, RFF: %d, n: %d\n", vpriv->trf, tff >> 7, rff >> 1, n);
1683 1609
1684 vpriv->display_frame += n; 1610 vpriv->display_frame += n;
1685 if(! vpriv->vframes) 1611 if(! vpriv->vframes)
1686 mp_msg(MSGT_MUXER, MSGL_INFO, "\nENABLED SOFT TELECINING, FPS=%s, INITIAL PATTERN IS TFF:%d, RFF:%d\n", 1612 mp_msg(MSGT_MUXER, MSGL_INFO, "\nENABLED SOFT TELECINING, FPS=%.3f, INITIAL PATTERN IS TFF:%d, RFF:%d\n",
1687 framerates[(vpriv->telecine == TELECINE_FILM2PAL) ? FRAMERATE_25 : fps+3], tff >> 7, rff >> 1); 1613 conf_vframerate, tff >> 7, rff >> 1);
1688 1614
1689 return 1; 1615 return 1;
1690 } 1616 }
1691 1617
1692 static size_t parse_mpeg12_video(muxer_stream_t *s, muxer_priv_t *priv, muxer_headers_t *spriv, float fps, size_t len) 1618 static size_t parse_mpeg12_video(muxer_stream_t *s, muxer_priv_t *priv, muxer_headers_t *spriv, float fps, size_t len)
2664 { 2590 {
2665 mp_msg(MSGT_MUXER, MSGL_ERR, "ERROR: options 'telecine' and 'vframerate' are mutually exclusive, vframerate disabled\n"); 2591 mp_msg(MSGT_MUXER, MSGL_ERR, "ERROR: options 'telecine' and 'vframerate' are mutually exclusive, vframerate disabled\n");
2666 conf_vframerate = 0; 2592 conf_vframerate = 0;
2667 } 2593 }
2668 2594
2595 if(conf_telecine == TELECINE_FILM2PAL)
2596 {
2597 if(conf_telecine_src==0.0f) conf_telecine_src = 24000.0/1001.0;
2598 conf_telecine_dest = 25;
2599 conf_telecine = TELECINE_DGPULLDOWN;
2600 }
2601 else if(conf_telecine == PULLDOWN32)
2602 {
2603 if(conf_telecine_src==0.0f) conf_telecine_src = 24000.0/1001.0;
2604 conf_telecine_dest = 30000.0/1001.0;
2605 conf_telecine = TELECINE_DGPULLDOWN;
2606 }
2607
2669 if(conf_telecine_src>0 && conf_telecine_dest>0 && conf_telecine_src < conf_telecine_dest) 2608 if(conf_telecine_src>0 && conf_telecine_dest>0 && conf_telecine_src < conf_telecine_dest)
2670 { 2609 {
2671 int snum, sden, tnum, tden, sfps, tfps; 2610 int snum, sden, tnum, tden, sfps, tfps;
2672 2611
2673 sfps = (int) (conf_telecine_src * 1001 + 0.5); 2612 sfps = (int) (conf_telecine_src * 1001 + 0.5);