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