Mercurial > mplayer.hg
comparison libmpdemux/muxer_mpeg.c @ 22330:3e9ffa27ca7f
simplified parse_mpeg12_video()
author | nicodvb |
---|---|
date | Sun, 25 Feb 2007 22:40:05 +0000 |
parents | 42d21ca22e7e |
children | e0b491ce664a |
comparison
equal
deleted
inserted
replaced
22329:e65d1a3e4e15 | 22330:3e9ffa27ca7f |
---|---|
1605 uint8_t *fps_ptr = NULL; //pointer to the fps byte in the sequence header | 1605 uint8_t *fps_ptr = NULL; //pointer to the fps byte in the sequence header |
1606 uint8_t *se_ptr = NULL; //pointer to sequence extension | 1606 uint8_t *se_ptr = NULL; //pointer to sequence extension |
1607 uint8_t *pce_ptr = NULL; //pointer to picture coding extension | 1607 uint8_t *pce_ptr = NULL; //pointer to picture coding extension |
1608 int frames_diff, d1, gop_reset = 0; //how any frames we advanced respect to the last one | 1608 int frames_diff, d1, gop_reset = 0; //how any frames we advanced respect to the last one |
1609 int ret; | 1609 int ret; |
1610 int i, err; | |
1611 uint32_t temp_ref; | |
1612 int pt; | |
1610 | 1613 |
1611 mp_msg(MSGT_MUXER, MSGL_DBG2,"parse_mpeg12_video, len=%u\n", (uint32_t) len); | 1614 mp_msg(MSGT_MUXER, MSGL_DBG2,"parse_mpeg12_video, len=%u\n", (uint32_t) len); |
1612 if(s->buffer[0] != 0 || s->buffer[1] != 0 || s->buffer[2] != 1 || len<6) | 1615 if(s->buffer[0] != 0 || s->buffer[1] != 0 || s->buffer[2] != 1 || len<6) |
1613 { | 1616 { |
1614 mp_msg(MSGT_MUXER, MSGL_ERR,"Unknown video format, possibly non-MPEG1/2 stream, len=%d!\n", len); | 1617 mp_msg(MSGT_MUXER, MSGL_ERR,"Unknown video format, possibly non-MPEG1/2 stream, len=%d!\n", len); |
1615 return 0; | 1618 return 0; |
1616 } | 1619 } |
1617 | 1620 |
1618 if(s->buffer[3] == 0 || s->buffer[3] == 0xb3 || s->buffer[3] == 0xb8) | 1621 temp_ref = 0; |
1622 pt = 0; | |
1623 err = 0; | |
1624 i = 0; | |
1625 while(i + 4 < len) | |
1619 { // Video (0) Sequence header (b3) or GOP (b8) | 1626 { // Video (0) Sequence header (b3) or GOP (b8) |
1620 uint32_t temp_ref; | 1627 if((s->buffer[i] == 0) && (s->buffer[i+1] == 0) && (s->buffer[i+2] == 1)) |
1621 int pt; | 1628 { |
1622 | 1629 switch(s->buffer[i+3]) |
1623 if(s->buffer[3] == 0xb3) //sequence | |
1624 { | |
1625 fps_ptr = &(s->buffer[7]); | |
1626 mp_header_process_sequence_header(&(spriv->picture), &(s->buffer[4])); | |
1627 spriv->delta_pts = spriv->nom_delta_pts = parse_fps(spriv->picture.fps); | |
1628 | |
1629 spriv->delta_clock = (double) 1/fps; | |
1630 //the 2 lines below are needed to handle non-standard frame rates (such as 18) | |
1631 if(! spriv->delta_pts) | |
1632 spriv->delta_pts = spriv->nom_delta_pts = (uint64_t) ((double)27000000.0 * spriv->delta_clock ); | |
1633 mp_msg(MSGT_MUXER, MSGL_DBG2, "\nFPS: %.3f, FRAMETIME: %.3lf\n", fps, (double)1/fps); | |
1634 if(priv->patch_seq) | |
1635 patch_seq(priv, s->buffer); | |
1636 | |
1637 tmp = 12; | |
1638 if(s->buffer[tmp-1] & 2) | |
1639 tmp += 64; | |
1640 | |
1641 if(s->buffer[tmp-1] & 1) | |
1642 tmp += 64; | |
1643 | |
1644 if(s->buffer[tmp] == 0 && s->buffer[tmp+1] == 0 && s->buffer[tmp+2] == 1 && s->buffer[tmp+3] == 0xb5) | |
1645 { | 1630 { |
1646 se_ptr = &(s->buffer[tmp+4]); | 1631 case 0xb3: //sequence |
1647 mp_header_process_extension(&(spriv->picture), &(s->buffer[tmp+4])); | 1632 { |
1648 } | 1633 if(i + 11 > len) |
1649 } | 1634 { |
1650 | 1635 err=1; |
1651 | 1636 break; |
1652 if(spriv->picture.mpeg1 == 0 && priv->patch_sde) | 1637 } |
1653 { | 1638 fps_ptr = &(s->buffer[i+7]); |
1654 while((s->buffer[tmp] != 0 || s->buffer[tmp+1] != 0 || s->buffer[tmp+2] != 1 || s->buffer[tmp+3] != 0xb5 || | 1639 mp_header_process_sequence_header(&(spriv->picture), &(s->buffer[i+4])); |
1655 ((s->buffer[tmp+4] & 0xf0) != 0x20)) && | 1640 spriv->delta_pts = spriv->nom_delta_pts = parse_fps(spriv->picture.fps); |
1656 (tmp < len-5)) | 1641 |
1657 tmp++; | 1642 spriv->delta_clock = (double) 1/fps; |
1658 | 1643 //the 2 lines below are needed to handle non-standard frame rates (such as 18) |
1659 if(tmp < len-5) //found | 1644 if(! spriv->delta_pts) |
1660 patch_panscan(priv, &(s->buffer[tmp+4])); | 1645 spriv->delta_pts = spriv->nom_delta_pts = (uint64_t) ((double)27000000.0 * spriv->delta_clock ); |
1661 } | 1646 mp_msg(MSGT_MUXER, MSGL_DBG2, "\nFPS: %.3f, FRAMETIME: %.3lf\n", fps, (double)1/fps); |
1662 | 1647 if(priv->patch_seq) |
1663 | 1648 patch_seq(priv, &(s->buffer[i])); |
1664 if(s->buffer[3]) | 1649 } |
1665 { // Sequence or GOP -- scan for Picture | 1650 break; |
1666 do_loop: while (ptr < len-5 && | 1651 |
1667 (s->buffer[ptr] != 0 || s->buffer[ptr+1] != 0 || s->buffer[ptr+2] != 1)) | 1652 case 0xb5: |
1668 ptr++; | 1653 if(i + 9 > len) |
1669 | 1654 { |
1670 if(s->buffer[ptr+3] == 0xb8) | 1655 err = 1; |
1671 gop_reset = 1; | 1656 break; |
1672 | 1657 } |
1673 if(s->buffer[ptr+3]) //not frame | 1658 mp_header_process_extension(&(spriv->picture), &(s->buffer[i+4])); |
1674 { | 1659 if(((s->buffer[i+4] & 0xf0) == 0x20)) |
1675 ptr++; | 1660 { |
1676 goto do_loop; | 1661 se_ptr = &(s->buffer[i+4]); |
1677 } | 1662 if(priv->patch_sde) |
1678 } | 1663 patch_panscan(priv, se_ptr); |
1679 | 1664 } |
1680 if (ptr >= len-5) | 1665 if((s->buffer[i+4] & 0xf0) == 0x80) |
1681 { | 1666 { |
1682 pt = 0; // Picture not found?! | 1667 pce_ptr = &(s->buffer[i+4]); |
1683 temp_ref = 0; | 1668 } |
1684 mp_msg(MSGT_MUXER, MSGL_ERR,"Warning: picture not found in GOP!\n"); | 1669 break; |
1685 } | 1670 |
1686 else | 1671 case 0xb8: |
1687 { | 1672 gop_reset = 1; |
1673 break; | |
1674 | |
1675 case 0x00: | |
1676 if(i + 5 > len) | |
1677 { | |
1678 err = 1; | |
1679 break; | |
1680 } | |
1681 pt = (s->buffer[i+5] & 0x1c) >> 3; | |
1682 temp_ref = (s->buffer[i+4]<<2)+(s->buffer[i+5]>>6); | |
1683 break; | |
1684 } | |
1685 if(err) break; //something went wrong | |
1686 if(s->buffer[i+3] >= 0x01 && s->buffer[i+3] <= 0xAF) break; //slice, we have already analized what we need | |
1687 } | |
1688 i++; | |
1689 } | |
1690 if(err) | |
1691 mp_msg(MSGT_MUXER, MSGL_ERR,"Warning: picture too short or broken!\n"); | |
1692 | |
1688 //following 2 lines are workaround: lavf doesn't sync to sequence headers before passing demux_packets | 1693 //following 2 lines are workaround: lavf doesn't sync to sequence headers before passing demux_packets |
1689 if(!spriv->nom_delta_pts) | 1694 if(!spriv->nom_delta_pts) |
1690 spriv->delta_pts = spriv->nom_delta_pts = parse_fps(fps); | 1695 spriv->delta_pts = spriv->nom_delta_pts = parse_fps(fps); |
1691 pt = (s->buffer[ptr+5] & 0x1c) >> 3; | |
1692 temp_ref = (s->buffer[ptr+4]<<2)+(s->buffer[ptr+5]>>6); | |
1693 if(!spriv->vframes) | 1696 if(!spriv->vframes) |
1694 spriv->last_tr = spriv->max_tr = temp_ref; | 1697 spriv->last_tr = spriv->max_tr = temp_ref; |
1695 d1 = temp_ref - spriv->last_tr; | 1698 d1 = temp_ref - spriv->last_tr; |
1696 if(gop_reset) | 1699 if(gop_reset) |
1697 frames_diff = spriv->max_tr + 1 + temp_ref - spriv->last_tr; | 1700 frames_diff = spriv->max_tr + 1 + temp_ref - spriv->last_tr; |
1713 spriv->max_tr = temp_ref; | 1716 spriv->max_tr = temp_ref; |
1714 | 1717 |
1715 spriv->last_tr = temp_ref; | 1718 spriv->last_tr = temp_ref; |
1716 if(spriv->picture.mpeg1 == 0) | 1719 if(spriv->picture.mpeg1 == 0) |
1717 { | 1720 { |
1718 size_t tmp = ptr; | 1721 if(spriv->telecine && pce_ptr) |
1719 | |
1720 while (ptr < len-5 && | |
1721 (s->buffer[ptr] != 0 || s->buffer[ptr+1] != 0 || s->buffer[ptr+2] != 1 || s->buffer[ptr+3] != 0xb5)) | |
1722 ptr++; | |
1723 if(ptr < len-5) | |
1724 { | 1722 { |
1725 pce_ptr = &(s->buffer[ptr+4]); | |
1726 if(spriv->telecine) | |
1727 soft_telecine(priv, spriv, fps_ptr, se_ptr, pce_ptr, frames_diff); | 1723 soft_telecine(priv, spriv, fps_ptr, se_ptr, pce_ptr, frames_diff); |
1728 spriv->picture.display_time = 100; | 1724 spriv->picture.display_time = 100; |
1729 mp_header_process_extension(&(spriv->picture), &(s->buffer[ptr+4])); | 1725 mp_header_process_extension(&(spriv->picture), pce_ptr); |
1730 if(spriv->picture.display_time >= 50 && spriv->picture.display_time <= 300) | 1726 if(spriv->picture.display_time >= 50 && spriv->picture.display_time <= 300) |
1731 spriv->delta_pts = (spriv->nom_delta_pts * spriv->picture.display_time) / 100; | 1727 spriv->delta_pts = (spriv->nom_delta_pts * spriv->picture.display_time) / 100; |
1732 } | 1728 } |
1733 else | |
1734 spriv->delta_pts = spriv->nom_delta_pts; | |
1735 | |
1736 ptr = tmp; | |
1737 } | 1729 } |
1738 } | |
1739 | 1730 |
1740 if(! spriv->vframes) | 1731 if(! spriv->vframes) |
1741 frames_diff = 1; | 1732 frames_diff = 1; |
1742 | 1733 |
1743 spriv->last_dts += spriv->delta_pts; | 1734 spriv->last_dts += spriv->delta_pts; |
1774 n, diff, (double) diff/27000000.0f, (double) spriv->last_pts/27000000.0f); | 1765 n, diff, (double) diff/27000000.0f, (double) spriv->last_pts/27000000.0f); |
1775 spriv->last_pts = spriv->last_dts; | 1766 spriv->last_pts = spriv->last_dts; |
1776 } | 1767 } |
1777 } | 1768 } |
1778 spriv->vframes++; | 1769 spriv->vframes++; |
1779 } | |
1780 | 1770 |
1781 mp_msg(MSGT_MUXER, MSGL_DBG2,"parse_mpeg12_video, return %u\n", (uint32_t) len); | 1771 mp_msg(MSGT_MUXER, MSGL_DBG2,"parse_mpeg12_video, return %u\n", (uint32_t) len); |
1782 return len; | 1772 return len; |
1783 } | 1773 } |
1784 | 1774 |